簡體   English   中英

使用 SQL 計算以年為單位的確切日期差異

[英]Calculate exact date difference in years using SQL

我收到報告,其中數據自動ETL到數據庫。 我提取並轉換了一些數據以將其加載到其他地方。 我需要做的一件事是DATEDIFF但年份需要准確(即 4.6 年而不是四舍五入到五年。

以下是我的腳本:

select *, DATEDIFF (yy, Begin_date, GETDATE()) AS 'Age in Years'
from Report_Stage;

'Age_In_Years'列正在四舍五入。 我如何獲得以年為單位的確切日期?

datediff()所做的只是計算兩個日期之間跨越的周期邊界數。 例如

datediff(yy,'31 Dec 2013','1 Jan 2014')

返回 1。

如果以天為單位計算兩個日期之間的差異,然后除以 400 年跨度 (365.2425) 中以天為單位的日歷年的平均長度,您將獲得更准確的結果:

datediff(day,{start-date},{end-date},) / 365.2425

例如,

select datediff(day,'1 Jan 2000' ,'18 April 2014') / 365.2425

返回14.29461248 — 將其四舍五入到所需的精度。

您是否嘗試過以月為單位計算差異,然后以這種方式計算年份? 例如 30 個月/12 年就是 2.5 年。

編輯:此 SQL 查詢包含幾種計算日期差異的方法:

SELECT CONVERT(date, GetDate() - 912) AS calcDate
      ,DATEDIFF(DAY, GetDate() - 912, GetDate()) diffDays
      ,DATEDIFF(DAY, GetDate() - 912, GetDate()) / 365.0 diffDaysCalc
      ,DATEDIFF(MONTH, GetDate() - 912, GetDate()) diffMonths
      ,DATEDIFF(MONTH, GetDate() - 912, GetDate()) / 12.0 diffMonthsCalc
      ,DATEDIFF(YEAR, GetDate() - 912, GetDate()) diffYears

我認為除以 365.2425 不是一個好方法。 沒有任何部門可以完全准確地做到這一點(使用 365.25 也有問題)。

我知道以下腳本可以計算准確的日期差異(盡管可能不是最快捷的方式):

        declare @d1 datetime ,@d2 datetime
        --set your dates eg: 
        select @d1 = '1901-03-02'
        select @d2 = '2016-03-01'

        select DATEDIFF(yy, @d1, @d2) -
            CASE WHEN MONTH(@d2) < MONTH(@d1) THEN 1
                 WHEN MONTH(@d2) > MONTH(@d1) THEN 0
                 WHEN DAY(@d2) < DAY(@d1) THEN 1
                 ELSE 0 END

         -- = 114 years

比較:

         select datediff(day,@d1 ,@d2) / 365.2425
         -- = 115 years => wrong!

你也許可以用除法計算小范圍,但為什么要冒險呢??

以下腳本可以幫助測試 yeardiff 函數(只需將 cast(datediff(day,@d1,@d2) / 365.2425 as int) 換成任何函數):

   declare @d1 datetime set @d1 = '1900-01-01'

   while(@d1 < '2016-01-01')
   begin
    declare @d2 datetime set @d2 = '2016-04-01'

    while(@d2 >= '1900-01-01')
    begin
        if (@d1 <= @d2 and dateadd(YEAR,     cast(datediff(day,@d1,@d2) / 365.2425 as int)      , @d1) > @d2)
        begin
            select 'not a year!!', @d1, @d2, cast(datediff(day,@d1,@d2) / 365.2425 as int)
        end

        set @d2 = dateadd(day,-1,@d2)
    end

    set @d1 = dateadd(day,1,@d1)
  end

我找到了更好的解決方案。 這假設第一個日期小於或等於第二個日期。

declare @dateTable table (date1 datetime, date2 datetime)
insert into @dateTable 
    select '2017-12-31', '2018-01-02' union
    select '2017-01-03', '2018-01-02' union 
    select '2017-01-02', '2018-01-02' union
    select '2017-01-01', '2018-01-02' union
    select '2016-12-01', '2018-01-02' union
    select '2016-01-03', '2018-01-02' union
    select '2016-01-02', '2018-01-02' union
    select '2016-01-01', '2018-01-02' 
select date1, date2, 
        case when ((DATEPART(year, date1) < DATEPART(year, date2)) and 
                    ((DATEPART(month, date1) <= DATEPART(month, date2)) and 
(DATEPART(day, date1) <= DATEPART(day, date2)) ))
                    then DATEDIFF(year, date1, date2)
            when (DATEPART(year, date1) < DATEPART(year, date2))
                    then DATEDIFF(year, date1, date2) - 1
            when (DATEPART(year, date1) = DATEPART(year, date2))
                    then 0
        end [YearsOfService]
from @dateTable

date1                   date2                   YearsOfService
----------------------- ----------------------- --------------
2016-01-01 00:00:00.000 2018-01-02 00:00:00.000 2
2016-01-02 00:00:00.000 2018-01-02 00:00:00.000 2
2016-01-03 00:00:00.000 2018-01-02 00:00:00.000 1
2016-12-01 00:00:00.000 2018-01-02 00:00:00.000 1
2017-01-01 00:00:00.000 2018-01-02 00:00:00.000 1
2017-01-02 00:00:00.000 2018-01-02 00:00:00.000 1
2017-01-03 00:00:00.000 2018-01-02 00:00:00.000 0
2017-12-31 00:00:00.000 2018-01-02 00:00:00.000 0

您想要年差,但當未來日期的“一年中的某一天”小於過去日期的“年份”時減 1。 所以像這樣:

SELECT *
,DATEDIFF(YEAR, [Begin_date], [End_Date])
 + CASE WHEN CAST(DATENAME(DAYOFYEAR, [End_Date]) AS INT)
          >= CAST(DATENAME(DAYOFYEAR, [Begin_date]) AS INT)
   THEN 0 ELSE -1 END
 AS 'Age in Years'
from [myTable];

對我來說,我計算天數的差異

Declare @startDate datetime
Declare @endDate datetime
Declare @diff int
select @diff=datediff(day,@startDate,@endDate)
if (@diff>=365) then select '1Year'
if (@diff>=730) then select '2Years'

-----etc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM