Berechnen Sie den genauen datesunterschied in Jahren mit SQL

Ich empfange Berichte, in denen die data ETL an die DB automatisch sind. Ich extrahiere und verwandle etwas von diesen data, um es irgendwo anders zu laden. Eine Sache, die ich tun muss, ist ein DATEDIFF aber das Jahr muss genau sein (dh 4,6 Jahre statt Runden bis zu fünf Jahren.

Das folgende ist mein Skript:

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

Die Spalte 'Age_In_Years' wird abgerundet. Wie bekomme ich das genaue date in Jahren?

Hast du versucht, den Unterschied in Monaten zu bekommen und dann die Jahre so zu berechnen? Zum Beispiel 30 Monate / 12 wäre 2,5 Jahre.

Bearbeiten: Diese SQL-Abfrage enthält mehrere Ansätze zur Berechnung der datesdifferenz:

 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 

Alle datediff() ist berechnen die Anzahl der Periodengrenzen zwischen den data gekreuzt. Zum Beispiel

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

gibt 1 zurück.

Sie erhalten ein genaueres Ergebnis, wenn Sie den Unterschied zwischen den beiden Tagen in Tagen berechnen und durch die mittlere Länge eines Kalenderjahres in Tagen über einen timeraum von 400 Jahren (365.2425) teilen:

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

Zum Beispiel,

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

Rückkehr 14.29461248 – gerade um die gewünschte Präzision.

Ich denke, dass Division durch 365.2425 ist nicht ein guter path, dies zu tun. Keine Teilung kann dies ganz genau (mit 365.25 hat auch Probleme).

Ich weiß, das folgende Skript berechnet einen genauen datesunterschied (obwohl vielleicht nicht der schnellste path):

  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 

Zum Vergleich:

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

Sie können in der Lage, kleine Bereiche mit Teilung zu berechnen, aber warum nehmen Sie eine Chance?

Das folgende Skript kann helfen, Yardiff-functionen zu testing (nur Swap-Cast (Datediff (Tag, @ d1, @ d2) / 365.2425 als int) zu was auch immer die function ist):

  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