我有一个表,上面列出了人们的出生日期(目前是nvarchar(25))
我如何将其转换为日期,然后以年为单位计算他们的年龄?
我的数据如下所示
ID Name DOB
1 John 1992-01-09 00:00:00
2 Sally 1959-05-20 00:00:00
我希望看到:
ID Name AGE DOB
1 John 17 1992-01-09 00:00:00
2 Sally 50 1959-05-20 00:00:00
因为没有一个简单的答案总是能给出正确的年龄,下面是我想到的。
SELECT DATEDIFF(YY, DateOfBirth, GETDATE()) -
CASE WHEN RIGHT(CONVERT(VARCHAR(6), GETDATE(), 12), 4) >=
RIGHT(CONVERT(VARCHAR(6), DateOfBirth, 12), 4)
THEN 0 ELSE 1 END AS AGE
这将获得出生日期和当前日期之间的年差。如果出生日期还没过,就减去一年。
任何时候都是准确的——不管闰年或离生日有多近。
最棒的是——没有功能。
CASE WHEN datepart(MM, getdate()) < datepart(MM, BIRTHDATE) THEN ((datepart(YYYY, getdate()) - datepart(YYYY, BIRTH_DATE)) -1 )
ELSE
CASE WHEN datepart(MM, getdate()) = datepart(MM, BIRTHDATE)
THEN
CASE WHEN datepart(DD, getdate()) < datepart(DD, BIRTHDATE) THEN ((datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE)) -1 )
ELSE (datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE))
END
ELSE (datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE)) END
END
编辑:这个答案不正确。我把它放在这里,作为对那些试图使用dayofyear的人的警告,并在最后进行了进一步的编辑。
如果你像我一样,不想用小数天数来除法,或者冒着四舍五入/闰年错误的风险,我为https://stackoverflow.com/a/1572257/489865上面的@Bacon Bits评论鼓掌,他说:
如果我们在讨论人类的年龄,你应该这样计算
人类会计算年龄。这与地球的速度无关
移动和所有与日历有关的东西。每次都一样
月和日随着出生日期推移,年龄增加1。
这意味着下面是最准确的,因为它反映了什么
人类说“年龄”是指年龄。
然后他提出:
DATEDIFF(yy, @date, GETDATE()) -
CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE()))
THEN 1 ELSE 0 END
这里有几个建议涉及比较月和日(有些是错误的,没有考虑到这里正确的OR !)。但是没有人提出“dayofyear”这个词,因为它看起来既简单又短。我的报价:
DATEDIFF(year, @date, GETDATE()) -
CASE WHEN DATEPART(dayofyear, @date) > DATEPART(dayofyear, GETDATE()) THEN 1 ELSE 0 END
[注意:SQL BOL/MSDN中没有DATEPART(dayofyear,…)返回的实际文档!]我的理解是1- 366之间的数字;最重要的是,它不会根据DATEPART(工作日,…)和SET DATEFIRST而改变。]
编辑:dayofyear错误的原因:正如用户@AeroX评论的那样,如果出生/开始日期在非闰年的2月之后,当当前/结束日期是闰年时,年龄将提前一天增加。'2015-05-26', '2016-05-25'给出的年龄是1,而它应该仍然是0。比较不同年份的日期显然是危险的。因此使用MONTH()和DAY()是必要的。