November 17, 2014 at 5:45 pm
Comments posted to this topic are about the item Calculate age - Most easiest way
December 2, 2014 at 2:21 am
If you only need age in years, then the following is easier as it does not need you to create a function so can be used directly in a select statement. It calculates age by converting the dates to yyyymmdd format, subracting one from the other, diving by 10000 and rounding down.
FLOOR((CONVERT(INT,CONVERT(CHAR(8),GETDATE(),112))
- CONVERT(INT,CONVERT(CHAR(8),[dob],112)))/10000)
December 2, 2014 at 4:57 am
Neat, although isn't the Floor function obsolete, since you're performing an Integer Division?
December 2, 2014 at 5:21 am
I've always liked this to get the age in years
select cast(datediff(d,@dob,getdate())/365.25 as int)
December 2, 2014 at 6:01 am
andrew_dale (12/2/2014)
If you only need age in years, then the following is easier as it does not need you to create a function so can be used directly in a select statement. It calculates age by converting the dates to yyyymmdd format, subracting one from the other, diving by 10000 and rounding down.
FLOOR((CONVERT(INT,CONVERT(CHAR(8),GETDATE(),112))
- CONVERT(INT,CONVERT(CHAR(8),[dob],112)))/10000)
A person born on 2012-02-29 should be how old on 2014-02-28?
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
December 2, 2014 at 6:08 am
dave.ott 20779 (12/2/2014)
I've always liked this to get the age in yearsselect cast(datediff(d,@dob,getdate())/365.25 as int)
Try any date pair (DOB and reference date) where the month and the day are the same, such as
2012-03-02 and2014-03-02.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
December 2, 2014 at 6:09 am
A person born on 2012-02-29 should be how old on 2014-02-28?
1 year old still, the day has not rolled over to 1st March
select '20120228' , FLOOR((CONVERT(INT,'20140228') - CONVERT(INT,'20120228'))/10000) , FLOOR((CONVERT(INT,'20140301') - CONVERT(INT,'20120228'))/10000)
union all
select '20120229' , FLOOR((CONVERT(INT,'20140228') - CONVERT(INT,'20120229'))/10000) , FLOOR((CONVERT(INT,'20140301') - CONVERT(INT,'20120229'))/10000)
union all
select '20120301' , FLOOR((CONVERT(INT,'20140228') - CONVERT(INT,'20120301'))/10000) , FLOOR((CONVERT(INT,'20140301') - CONVERT(INT,'20120301'))/10000)
2012022822
2012022912
2012030112
December 2, 2014 at 6:21 am
Could the if statement be simplified to be...
if datediff(dd,dateadd(yy,@age,@dob),@getdate) < 0
set @age = @age - 1
December 2, 2014 at 6:22 am
andrew_dale (12/2/2014)
A person born on 2012-02-29 should be how old on 2014-02-28?
1 year old still, the day has not rolled over to 1st March
select '20120228' , FLOOR((CONVERT(INT,'20140228') - CONVERT(INT,'20120228'))/10000) , FLOOR((CONVERT(INT,'20140301') - CONVERT(INT,'20120228'))/10000)
union all
select '20120229' , FLOOR((CONVERT(INT,'20140228') - CONVERT(INT,'20120229'))/10000) , FLOOR((CONVERT(INT,'20140301') - CONVERT(INT,'20120229'))/10000)
union all
select '20120301' , FLOOR((CONVERT(INT,'20140228') - CONVERT(INT,'20120301'))/10000) , FLOOR((CONVERT(INT,'20140301') - CONVERT(INT,'20120301'))/10000)
2012022822
2012022912
2012030112
Most cultures celebrate the birthday of a "Leaper" on the 28th February, so a Leaper born on 2012-02-29 would celebrate their first birthday on 2013-02-28 and their second on 2014-02-28.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
December 2, 2014 at 6:25 am
Most cultures celebrate the birthday of a "Leaper" on the 28th February, so a Leaper born on 2012-02-29 would celebrate their first birthday on 2013-02-28 and their
second on 2014-02-28.
its the law in the UK that any person who was born on 29 February in a leap year will attain the age of 18 on 1 March in a non-leap year for the purpose of voting
December 2, 2014 at 8:20 am
dave.ott 20779 (12/2/2014)
I've always liked this to get the age in yearsselect cast(datediff(d,@dob,getdate())/365.25 as int)
This has problems on birthdays. As listed, the code returns 0 when dob = '12/2/2013' and getdate() = '12/2/2014'
Don Simpson
December 2, 2014 at 9:30 am
Yes there is an issue if the age is under 4 years.
I have used the prior version for adults and it works great, but for handling all birthdays
select cast(datediff(d,@dob,getdate())/case when datediff(yy,@dob,getdate())<4 then 365 else 365.25 end as int)
December 5, 2014 at 2:46 am
joseph.connor (12/2/2014)
Neat, although isn't the Floor function obsolete, since you're performing an Integer Division?
well spotted, I was guarding against it rounding up where fractional part was > 0.5, but integer division always truncates so you are right that the floor is not needed
http://msdn.microsoft.com/en-us/library/ms175009.aspx
If an integer dividend is divided by an integer divisor, the result is an integer that has any fractional part of the result truncated.
January 8, 2015 at 3:39 am
Great....Thanks for giving the nice input.....
January 23, 2015 at 12:08 pm
I find this works better than a scalar function...
CREATE FUNCTION dbo.AgeInYears
(
@BirthDate DATETIME2,
@AsOfDate DATETIME2
)
RETURNS TABLE
AS
RETURN
(
SELECT DATEDIFF(YEAR , @BirthDate , @AsOfDate) -
CASE WHEN DATEPART(DY, @AsOfDate) < DATEPART(DY, @BirthDate) THEN 1
ELSE 0
END AS Age
);
Then a simple CROSS APPLY in the query...
SELECT I.Name, I.Birthdate, A.Age
FROM Individual AS I
CROSS APPLY AgeInYears(I.Birthdate, CURRENT_TIMESTAMP) AS A
WHERE A.Age >= 18;
Viewing 15 posts - 1 through 15 (of 18 total)
You must be logged in to reply to this topic. Login to reply