我需要一些帮助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,
我非常感谢您对我的代码的任何帮助。
答案 0 :(得分:2)
小心闰年。你想如何对待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()
个案分开,主要是因为如果没有长线上的滚动条,它看起来会更好。
这是调整逻辑并捕捉闰日条件的一种方法,即使日期并不严格重合,也将其视为一整年。如果你按照我上面的方式保留“拆分”逻辑,你需要在两个分支中复制这个表达式(替换getdate() for
EndDateTime everywhere except the
为null`test)。
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)
)
顺便说一下,一旦你理解了这种方法,就可以用yyyymmdd格式的数字算术来压缩相同的逻辑。
(
cast(convert(varchar(8), @EndDateTime, 120) as int) -
cast(convert(varchar(8), @StartDateTime, 120) as int)
) / 10000
上面所有复杂的逻辑只是借用减法中的年份。这几乎是一回事。
答案 1 :(得分:1)
我认为应该是这样的:
SELECT StartDate
, EndDate
, CASE
WHEN DATEDIFF(YY, StartDate, ISNULL(EndDate, GETDATE())) < 0
THEN 0
ELSE DATEDIFF(YY, StartDate, ISNULL(EndDate, GETDATE()))
END AS AgingYears
FROM YourTableName