A little more about sql age calculation, as APC pointed it out, integer age can be given by the following expression:
floor(months_between(sysdate, dateofbirth)/12)
But, months_between
function treats end of month day specially. And this may raise an issue for leapers (someone born on the 29th of Feb), as taken from Wikipedia:
The effective legal date of a leapling's birthday in non-leap years varies between jurisdictions.
Putting in an example, on 28/02/1998, was someone born on 29/02/1988 10 years old or 9? Previous expression would yield 10, but in some areas it's 9.
In Teradata, this expression seems to be commonly used to allow leapers only turn one year old on 1st of March, instead of on 28 Feb, in non-leaping years:
select (extract(year from current_date) - extract(year from BIRTH_DATE) (named YEARS))
+ case when current_date - (YEARS (interval year)) < BIRTH_DATE
then -1 else 0 end
I think this expression should have the same effect and no case when
has to been invoked:
floor(least(months_between(CURRENT_DATE, BIRTH_DATE), months_between(CURRENT_DATE - 1, BIRTH_DATE - 1))/12)
I ran the following code to check the validity of this expression in Teradata:
select O.DATEO, N.DATEN,
(EXTRACT(YEAR FROM N.DATEN) - EXTRACT(YEAR FROM O.DATEO) (NAMED YEARS))
+ CASE WHEN ADD_MONTHS( N.DATEN , - YEARS * 12 ) < O.DATEO
THEN -1 ELSE 0 END AS AGE1,
floor(least(months_between(N.DATEN, O.DATEO), months_between(N.DATEN -1, O.DATEO- 1))/12) as AGE2,
AGE1 - AGE2
from
(select cast(calendar_date as date) as DATEO from sys_calendar.CALENDAR
where calendar_date between date '2000-01-01' and date '2013-01-01') as O
inner join
(select cast(calendar_date as date) as DATEN from sys_calendar.CALENDAR
where calendar_date between date '2000-01-01' and date '2013-01-01'
) as N
on N.DATEN > O.DATEO
where AGE1 <> AGE2;