2017-01-11 301 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