我做了很多思考和研究,我有三个解决方案
正确计算年龄
短(大部分)
(大部分)是可以理解的。
以下是测试值:
DECLARE @NOW DATETIME = '2013-07-04 23:59:59'
DECLARE @DOB DATETIME = '1986-07-05'
解决方案1:我在一个js库中找到了这种方法。这是我的最爱。
DATEDIFF(YY, @DOB, @NOW) -
CASE WHEN DATEADD(YY, DATEDIFF(YY, @DOB, @NOW), @DOB) > @NOW THEN 1 ELSE 0 END
它实际上是将年份的差异添加到DOB,如果它比当前日期大,则减去一年。简单的对吧?唯一不同的是,在这里,年龄的差异是相同的。
但是如果你不需要内联使用它,你可以这样写:
DECLARE @AGE INT = DATEDIFF(YY, @DOB, @NOW)
IF DATEADD(YY, @AGE, @DOB) > @NOW
SET @AGE = @AGE - 1
解决方案2:这个我最初是从@bacon-bits复制的。这是最容易理解的,但有点长。
DATEDIFF(YY, @DOB, @NOW) -
CASE WHEN MONTH(@DOB) > MONTH(@NOW)
OR MONTH(@DOB) = MONTH(@NOW) AND DAY(@DOB) > DAY(@NOW)
THEN 1 ELSE 0 END
它基本上是像我们人类一样计算年龄。
解决方案3:我的朋友将其重构为:
DATEDIFF(YY, @DOB, @NOW) -
CEILING(0.5 * SIGN((MONTH(@DOB) - MONTH(@NOW)) * 50 + DAY(@DOB) - DAY(@NOW)))
这个是最短的,但也是最难理解的。50只是一个重量,所以只有在月份相同的情况下,日差才重要。SIGN函数是用来将任意值转换为- 1,0或1的。CEILING(0.5 *与Math相同。max(0, value),但是在SQL中没有这样的东西。