Finding someone's age in SQL

前端 未结 7 2277
孤街浪徒
孤街浪徒 2020-12-16 21:11

In a SQL Server database, I record people\'s date of birth. Is there an straight-forward method of working out the person\'s age on a given date using SQL only?

Usi

相关标签:
7条回答
  • 2020-12-16 21:58
    SELECT Pname, DOB, DATEDIFF(YEAR, DOB, GETDATE()) AS Age
    FROM tablename
    
    0 讨论(0)
  • 2020-12-16 22:04

    This is more concise and a bit faster than the answers provided, and completely accurate:

    datediff(year,DateOfBirth,getdate()-datepart(dy,DateOfBirth)+1)
    
    0 讨论(0)
  • 2020-12-16 22:05

    There is another way that is a bit simpler:

    Select CAST(DATEDIFF(hh, [birthdate], GETDATE()) / 8766 AS int) AS Age
    

    Because the rounding here is very granular, this is almost perfectly accurate. The exceptions are so convoluted that they are almost humorous: every fourth year the age returned will be one year too young if we A) ask for the age before 6:00 AM, B) on the person's birthday and C) their birthday is after February 28th. In my setting, this is a perfectly acceptable compromise.

    0 讨论(0)
  • 2020-12-16 22:05

    I hope this one is perfect provided you accept the algorithm that a leap-baby turns a year older on successive February 29th's, or March 1's on non-leap years. @DOB must contain a date within a few centuries of now, @AsOf must contain a similar date >= @DOB:

    SET @Age = YEAR(@AsOf) - YEAR(@DOB) - 1
    IF MONTH(@AsOf) * 100 + DAY(@AsOf) >= MONTH(@DOB) * 100 + DAY(@DOB)
        SET @Age = @Age + 1
    

    I'd REALLY REALLY appreciate any testing and comments as I haven't found a way yet to break it... yet.

    Added - 1/31/2014: This one seems to work perfectly too even though at first glance it looks too crude:

    SET @Age = FLOOR(DATEDIFF(dd,@DOB,@CompareDate)/365.25)
    

    Pop these in a function and here's a test script:

        SELECT dbo.fnGetAge('2/27/2008', '2/27/2012')
        SELECT dbo.fnGetAge('2/27/2008', '2/28/2012')
        SELECT dbo.fnGetAge('2/27/2008', '2/29/2012')
        SELECT dbo.fnGetAge('2/27/2008', '3/1/2012')
        -- 4 4 4 4
        SELECT dbo.fnGetAge('2/28/2008', '2/27/2012')
        SELECT dbo.fnGetAge('2/28/2008', '2/28/2012')
        SELECT dbo.fnGetAge('2/28/2008', '2/29/2012')
        SELECT dbo.fnGetAge('2/28/2008', '3/1/2012')
        -- 3 4 4 4
        SELECT dbo.fnGetAge('2/29/2008', '2/27/2012')
        SELECT dbo.fnGetAge('2/29/2008', '2/28/2012')
        SELECT dbo.fnGetAge('2/29/2008', '2/29/2012')
        SELECT dbo.fnGetAge('2/29/2008', '3/1/2012')
        -- 3 3 4 4
        SELECT dbo.fnGetAge('3/1/2008', '2/27/2012')
        SELECT dbo.fnGetAge('3/1/2008', '2/28/2012')
        SELECT dbo.fnGetAge('3/1/2008', '2/29/2012')
        SELECT dbo.fnGetAge('3/1/2008', '3/1/2012')
        -- 3 3 3 4
        SELECT dbo.fnGetAge('3/1/2007', '2/27/2012')
        SELECT dbo.fnGetAge('3/1/2007', '2/28/2012')
        SELECT dbo.fnGetAge('3/1/2007', '2/29/2012')
        SELECT dbo.fnGetAge('3/1/2007', '3/1/2012')
        -- 4 4 4 5
        SELECT dbo.fnGetAge('3/1/2007', '2/27/2013')
        SELECT dbo.fnGetAge('3/1/2007', '2/28/2013')
        SELECT dbo.fnGetAge('3/1/2007', '3/1/2013')
        SELECT dbo.fnGetAge('2/27/2007', '2/28/2013')
        SELECT dbo.fnGetAge('2/28/2007', '2/28/2014')
        -- 5 5 6 6 7
    

    Cheers

    PS: You can probably tweak the February 29 decision to being a day earlier if that floats your boat.

    0 讨论(0)
  • 2020-12-16 22:10

    FWIW, Age can be computed in a straightforward manner without resorting to hacks (not that there's anything wrong with hacks!):

    CREATE FUNCTION Age (@BirthDate DATETIME)
    RETURNS INT
    AS
    BEGIN
        DECLARE @AgeOnBirthdayThisYear INT
        DECLARE @BirthdayThisYear DATETIME
        SET @AgeOnBirthdayThisYear = DATEDIFF(year, @BirthDate, GETDATE())
        SET @BirthdayThisYear = DATEADD(year, @AgeOnBirthdayThisYear, @BirthDate)
        RETURN
            @AgeOnBirthdayThisYear
            - CASE WHEN @BirthdayThisYear > GETDATE() THEN 1 ELSE 0 END
    END
    
    0 讨论(0)
  • 2020-12-16 22:10

    This solution show how in one query without variables

    SELECT DATEDIFF(YY, birthdate, GETDATE()) - CASE WHEN( (MONTH(birthdate)*100 + DAY(birthdate)) > (MONTH(GETDATE())*100 + DAY(GETDATE())) ) THEN 1 ELSE 0 END
    
    0 讨论(0)
提交回复
热议问题