代码之家  ›  专栏  ›  技术社区  ›  Tim C

在SQL中查找某人的年龄

  •  8
  • Tim C  · 技术社区  · 16 年前

    在SQL Server数据库中,我记录人们的出生日期。是否有一个直接的方法来计算一个人在给定日期的年龄,只使用SQL?

    使用 datediff(年,出生日期,getDate()) 不起作用,因为这只查看日期的年份部分。例如 日期差异(2007年12月31日、2008年1月1日) 返回1。

    7 回复  |  直到 9 年前
        1
  •  21
  •   scable    16 年前

    看看这篇文章: How to calculate age of a person using SQL codes

    这是本文的代码:

    DECLARE @BirthDate DATETIME
    DECLARE @CurrentDate DATETIME
    
    SELECT @CurrentDate = '20070210', @BirthDate = '19790519'
    
    SELECT DATEDIFF(YY, @BirthDate, @CurrentDate) - CASE WHEN( (MONTH(@BirthDate)*100 + DAY(@BirthDate)) > (MONTH(@CurrentDate)*100 + DAY(@CurrentDate)) ) THEN 1 ELSE 0 END 
    
        2
  •  5
  •   Mark Brittingham    16 年前

    还有另一种更简单的方法:

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

    因为这里的四舍五入很细,所以 几乎 非常准确。例外情况是如此复杂,他们几乎是幽默的:每四年,如果我们a)在6:00之前要求年龄,b)在人的生日,c)他们的生日在2月28日之后,返回的年龄将是一岁太小。在我看来,这是一个完全可以接受的妥协。

        3
  •  2
  •   John Pick    13 年前

    fwiw,年龄可以直接计算,而不需要借助黑客(不是说黑客有什么问题!):

    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
    
        4
  •  1
  •   Paul    12 年前

    这个解决方案展示了如何在一个没有变量的查询中

    SELECT DATEDIFF(YY, birthdate, GETDATE()) - CASE WHEN( (MONTH(birthdate)*100 + DAY(birthdate)) > (MONTH(GETDATE())*100 + DAY(GETDATE())) ) THEN 1 ELSE 0 END
    
        5
  •  1
  •   brianary    12 年前

    这比提供的答案更简洁、更快,并且完全准确:

    datediff(year,DateOfBirth,getdate()-datepart(dy,DateOfBirth)+1)
    
        6
  •  0
  •   user3255222    11 年前

    我希望这是完美的,只要你接受这样的算法:一个闰年婴儿在连续的2月29日或3月1日在非闰年变大。@dob必须包含几个世纪内的日期,@asof必须包含类似的日期>=@dob:

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

    我真的很感激任何测试和评论,因为我还没有找到打破它的方法…然而。

    补充-2014年1月31日:尽管乍一看它看起来太粗糙,但它似乎也能完美地工作:

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

    在函数中弹出这些,下面是一个测试脚本:

        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
    

    干杯

    附言:如果2月29日的决定能让你的船浮起来的话,你可以提前一天做出决定。

        7
  •  0
  •   Yaroslav Admin    9 年前
    SELECT Pname, DOB, DATEDIFF(YEAR, DOB, GETDATE()) AS Age
    FROM tablename