我需要一些有关SQL Server 2012的帮助,试图为报告计算“账龄”字段。
基本上,我有两个字段StartDateTime和EndDateTime,下面是一些示例数据:
StartDateTime EndDateTime
2006-10-10 16:08:13.523 2008-04-11 00:00:00.000
2016-05-11 13:03:48.093 2016-06-16 00:00:00.000
2016-08-01 12:44:42.990 2016-08-01 00:00:00.000
2016-05-20 17:33:27.957 2016-05-25 00:00:00.000
2006-10-19 21:41:41.350 NULL
我当前正在尝试使AgingYears字段来计算两个字段之间的帐龄(尽可能精确)。并且当EndDateTime为NULL时,它应该计算GETDATE()和StartDateTime之间的差。当StartDateTime大于EndDateTime(我不知道为什么会有这样的数据,但是我知道)时,它应该只返回0。
我尝试根据我发现的相关网站做一些代码,但这对我没有太大帮助,这就是我所坚持的地方:
DATEDIFF(YY, StartDateTime, EndDateTime) -
CASE
WHEN DATEADD(YY,DATEDIFF(YY,StartDateTime, EndDateTime),StartDateTime)
> A.[END_DTTM]
THEN DATEDIFF(YY, StartDateTime, EndDateTime)- 1
ELSE DATEDIFF(YY, StartDateTime, EndDateTime)
END AS AgeInYears,
我的代码的任何帮助将不胜感激。
最佳答案
leap年要小心。您希望2月29日至2月28日如何得到治疗?
case
when year(coalesce(EndDateTime, getdate()) > year(StartDateTime)
then
datediff(year, StartDateTime, coalesce(EndDateTime, getdate())) -
case
when
EndDateTime is not null and
datepart(month, EndDateTime) < datepart(month, StartDateTime)
or datepart(month, EndDateTime) = datepart(month, StartDateTime)
and datepart(day, EndDateTime) < datepart(day, StartDateTime)
then 1
when
EndDateTime is null and
datepart(month, getdate()) < datepart(month, StartDateTime)
or datepart(month, getdate()) = datepart(month, StartDateTime)
and datepart(day, getdate()) < datepart(day, StartDateTime)
then 1
else 0
end
else 0
end
我将
EndDateTime
和getdate()
情况分开,主要是因为在没有长行滚动条的情况下看起来更好。这是一种调整逻辑并捕获the日条件的方法,即使条件并不完全一致,也可以将其视为整年。如果您按照我上面编写的方式保留“split”逻辑,则需要在两个分支中都重复此表达式(将
getdate() for
EndDateTime everywhere except the
替换为null测试)。 when
EndDateTime is not null and
datepart(month, EndDateTime) < datepart(month, StartDateTime)
or datepart(month, EndDateTime) = datepart(month, StartDateTime)
and datepart(day, EndDateTime) < datepart(day, StartDateTime)
and not -- here's one way to catch the leap day condition
(
-- adding one day this way is deprecated and only works with datetime
and datepart(month, StartDateTime + 1) > datepart(month, StartDateTime)
and datepart(month, EndDateTime + 1) > datepart(month, EndDateTime)
)
http://rextester.com/SBH69843
顺便说一句,一旦您了解了这种方法,便有一种方法可以对yyyymmdd格式的数字使用算术来压缩相同的逻辑。
(
cast(convert(varchar(8), @EndDateTime, 120) as int) -
cast(convert(varchar(8), @StartDateTime, 120) as int)
) / 10000
上面所有复杂的逻辑只是从减法中的年份中借用的。几乎是同一回事。
关于sql - 用SQL计算岁数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41597762/