2017-01-11 304 views
3

我需要SQL Server 2012帮助来计算报告的年龄段。在SQL中计算年龄年龄

基本上,我有两个领域的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

你能告诉您的样本数据的预期效果? – Aducci

+0

[如何根据出生日期和getDate()]计算年龄(以年计)可能的重复(http://stackoverflow.com/questions/1572110/how-to-calculate-age-in-years-based-在出生日期和getdate) –

+1

@JeremyDanyow看来,在其他问题上的大部分答案是相当复杂,可能是错误的,虽然我确信有其他人确实有计算时代的方法(不管语言如何。) – shawnt00

回答

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 

我大多分裂EndDateTimegetdate()案件因为它看起来不会对排长队的滚动条更好。

这里有一种方法来调整逻辑,并捕捉闰日条件,即使日期并不严格一致,也可以将其视为整整一年。如果按照上面的方式保留“分割”逻辑,则需要在两个分支中复制此表达式(替代getdate() for EndDateTime everywhere except the为空'测试)。

  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 

以上所有复杂的逻辑都是简单地从减法中的年份中借用。这几乎是一回事。

+0

这看起来比必要的更复杂。 –

+0

这并不复杂。这是按月份排序日期(不同年份)的典型方法。 – shawnt00

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