The key to finding age is to find the birthday for the current year, and subtract 1 from the difference in years if the current date is before the birthday this year.
Note that the code below computes the current year birthday for Feb 29 birthdays as Feb 28 for non-leap years and Feb 29 for leap years.
The concept of negative age doesn't seem to have any real world meaning, so my method returns null if the date of birth is before current date.
select
a.DOB,
a.CURR_DATE,
Age =
datediff(yy,a.DOB,a.CURR_DATE) +
case
-- Age is null when DOB before current date
when datediff(dd,a.DOB,a.CURR_DATE) < 0
then null
-- Subtract 1 if current date before birthday in current year
when datediff(dd,dateadd(yy,datediff(yy,a.DOB,a.CURR_DATE),a.DOB),a.CURR_DATE) < 0
then -1 else 0 end
from
( -- Test Data
select
DOB =convert(datetime,'20040407'),
CURR_DATE = convert(datetime,'20060203')
union all
select getdate(),dateadd(ms,100,getdate()) union all
select getdate(),dateadd(ms,-100,getdate()) union all
select getdate(),dateadd(dd,-1,getdate()) union all
select getdate(),dateadd(yy,10,dateadd(ms,-100,getdate())) union all
select getdate(),dateadd(yy,10,dateadd(ms,100,getdate())) union all
select '20040407','20040407' union all
select '20040407','20050406' union all
select '20040407','20050407' union all
select '20040229','20060227' union all
select '20040229','20060228' union all
select '20040229','20060301' union all
select '20040229','20080228' union all
select '20040229','20080229' union all
select '20060205','20060205' union all
select '17530101 00:00:00.000','99991231 23:59:59.997' union all
select '19500913', getdate()
) a
order by
a.DOB,
a.CURR_DATE
Results:
DOB CURR_DATE Age
----------------------- ----------------------- -----------
1753-01-01 00:00:00.000 9999-12-31 23:59:59.997 8246
1950-09-13 00:00:00.000 2013-01-08 16:52:54.810 62
2004-02-29 00:00:00.000 2006-02-27 00:00:00.000 1
2004-02-29 00:00:00.000 2006-02-28 00:00:00.000 2
2004-02-29 00:00:00.000 2006-03-01 00:00:00.000 2
2004-02-29 00:00:00.000 2008-02-28 00:00:00.000 3
2004-02-29 00:00:00.000 2008-02-29 00:00:00.000 4
2004-04-07 00:00:00.000 2004-04-07 00:00:00.000 0
2004-04-07 00:00:00.000 2005-04-06 00:00:00.000 0
2004-04-07 00:00:00.000 2005-04-07 00:00:00.000 1
2004-04-07 00:00:00.000 2006-02-03 00:00:00.000 1
2006-02-05 00:00:00.000 2006-02-05 00:00:00.000 0
2013-01-08 16:52:54.810 2013-01-07 16:52:54.810 NULL
2013-01-08 16:52:54.810 2013-01-08 16:52:54.710 0
2013-01-08 16:52:54.810 2013-01-08 16:52:54.910 0
2013-01-08 16:52:54.810 2023-01-08 16:52:54.710 10
2013-01-08 16:52:54.810 2023-01-08 16:52:54.910 10