我有一个表,上面列出了人们的出生日期(目前是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
Ed Harper的解决方案是我发现的最简单的,当两个日期的月和日相隔1天或更少时,它永远不会返回错误的答案。我做了一个小小的修改来处理负年龄。
DECLARE @D1 AS DATETIME, @D2 AS DATETIME
SET @D2 = '2012-03-01 10:00:02'
SET @D1 = '2013-03-01 10:00:01'
SELECT
DATEDIFF(YEAR, @D1,@D2)
+
CASE
WHEN @D1<@D2 AND DATEADD(YEAR, DATEDIFF(YEAR,@D1, @D2), @D1) > @D2
THEN - 1
WHEN @D1>@D2 AND DATEADD(YEAR, DATEDIFF(YEAR,@D1, @D2), @D1) < @D2
THEN 1
ELSE 0
END AS AGE
Declare @dob datetime
Declare @today datetime
Set @dob = '05/20/2000'
set @today = getdate()
select CASE
WHEN dateadd(year, datediff (year, @dob, @today), @dob) > @today
THEN datediff (year, @dob, @today) - 1
ELSE datediff (year, @dob, @today)
END as Age
编辑:这个答案不正确。我把它放在这里,作为对那些试图使用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()是必要的。