我需要一些有关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

我将EndDateTimegetdate()情况分开,主要是因为在没有长行滚动条的情况下看起来更好。

这是一种调整逻辑并捕获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/

10-11 02:50