【问题标题】:Finding someone's age in SQL在 SQL 中查找某人的年龄
【发布时间】:2008-11-12 12:15:37
【问题描述】:

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

使用 DATEDIFF(YEAR, DateOfBirth, GETDATE()) 不起作用,因为这只查看日期的年份部分。例如 DATEDIFF(YEAR, '31 December 2007', '01 January 2008') 返回 1。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    查看这篇文章: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 
    

    【讨论】:

    • 您真的可以将相关代码放入您的答案中吗?指向其他网站的链接可能(并且确实)中断,因此如果该链接不再有效,那么将来此答案可能无用。
    • @Tim C +1 建议添加代码,因为该网站当前已关闭,并且仅使用链接此答案将毫无用处。
    【解决方案2】:

    还有一种更简单的方法:

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

    因为这里的舍入非常精细,所以这几乎完全准确。例外是如此令人费解,以至于它们几乎是幽默的:如果我们 A) 要求在早上 6:00 之前的年龄,B) 在这个人的生日和 C) 他们的生日在之后2 月 28 日。在我的环境中,这是一个完全可以接受的折衷方案。

    【讨论】:

    • 如果您将 GETDATE() 替换为静态值,您将更频繁地遇到异常,因为您在午夜进行检查。看起来从中午而不是午夜开始检查会起作用。
    【解决方案3】:

    FWIW,年龄可以以直接的方式计算,无需借助 hack(并不是说 hack 有什么问题!):

    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】:

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

      SELECT DATEDIFF(YY, birthdate, GETDATE()) - CASE WHEN( (MONTH(birthdate)*100 + DAY(birthdate)) > (MONTH(GETDATE())*100 + DAY(GETDATE())) ) THEN 1 ELSE 0 END
      

      【讨论】:

        【解决方案5】:

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

        datediff(year,DateOfBirth,getdate()-datepart(dy,DateOfBirth)+1)
        

        【讨论】:

        • GetDate() 为生日时,此方法无效。这是一个例子,这个人应该是 40 岁,但它只返回 39。SELECT datediff(year,'1/29/1973',CAST('1/29/2013' AS DATETIME)-datepart(dy,'1/29/1973'))
        【解决方案6】:

        如果您接受闰婴儿在连续 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
        

        我真的非常感谢任何测试和 cmets,因为我还没有找到破解它的方法......但是。

        添加 - 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
        

        干杯

        PS:你可以将 2 月 29 日的决定调整为提前一天,如果这让你觉得很合适的话。

        【讨论】:

          【解决方案7】:
          SELECT Pname, DOB, DATEDIFF(YEAR, DOB, GETDATE()) AS Age
          FROM tablename
          

          【讨论】:

          • 一点解释可以大有帮助
          猜你喜欢
          • 2010-11-10
          • 1970-01-01
          • 2015-05-22
          • 2011-02-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-22
          相关资源
          最近更新 更多