2009-07-10 9 views

Antwort

5

den Abstand zwischen zwei Terminen finden Sie DateDiff verwenden, und dann diesen Wert dividieren von 365

EDIT

Sie könnten natürlich auch Ihre eigene Funktion erstellen Sie den Job zu erledigen:

create function yearfrac (@d1 datetime, @d2 datetime) returns float 
as 
begin 
return abs(datediff(d, @d1, @d2))/365.00 
end 
+2

, die nicht auf das Standardverhalten der YEARFRAC Funktion entspricht. .. – Guffa

+0

@Guffa - guten Ruf, hatte den Unterschied nicht bemerkt. –

+0

richtig du bist, guffa, ich habe das vermisst. in Ihrer Version müssten Sie jedoch etwas wie meine * 365.00 * -Lösung oben tun, um die Division mit Dezimalzahlen zu arbeiten, sonst enden Sie immer mit 0. –

3

Für die Standardverwendung (zwei Datenparameter):

datediff(day, date1, date2)/360.0 

Für den speziellen Fall, in dem der dritte Parameter den Wert 3:

datediff(day, date1, date2)/365.0 

Edit:
Added eine Dezimalzahl es eine Gleitkomma-Operation zu machen.

+0

fyi, dies schneidet den Rückgabewert ab. –

-3

Ich weiß, dass dies ein wenig zu spät für eine Antwort ist aber nur für den Fall, dass jemand anderes stößt auf das hier ist das, was ich getan habe:

CREATE FUNCTION dbo.udfYearFrac 
(
    @StartDate AS DATETIME, 
    @EndDate AS DATETIME 
) 
RETURNS DECIMAL(18,6) 
AS 
BEGIN 
    DECLARE @YearFrac  AS DECIMAL(18,6) 
    DECLARE @nbDaysInPeriod AS INT 
    DECLARE @nbYears  AS INT 

    SELECT 
     @nbDaysInPeriod = DATEDIFF(DAY, @StartDate, @EndDate) 
     ,@nbYears = YEAR(@EndDate) - YEAR(@StartDate) + 1 

    SELECT @YearFrac = @nbDaysInPeriod/
     CASE WHEN YEAR(@StartDate) = YEAR(@EndDate) OR (YEAR(@EndDate)-1 = YEAR(@StartDate) AND (MONTH(@StartDate) > MONTH(@EndDate) OR MONTH(@StartDate) = MONTH(@EndDate) AND (DAY(@StartDate) >= DAY(@EndDate)))) 
     THEN 
      CASE WHEN YEAR(@StartDate) = YEAR(@EndDate) AND ISDATE(CAST(YEAR(@StartDate) AS CHAR(4)) + '0229') = 1 
      THEN 366.0 
      ELSE 
       CASE WHEN DAY(@EndDate) = 29 AND MONTH(@EndDate) = 2 
       THEN 366.0 
       ELSE 
        CASE WHEN ISDATE(CAST(YEAR(@StartDate) AS CHAR(4)) + '0229') = 1 
        THEN 
         CASE WHEN (@StartDate <= cast('2/29/' + cast(YEAR(@StartDate) AS CHAR(4)) AS DATETIME) AND cast('2/29/' + cast(YEAR(@StartDate) AS CHAR(4)) AS DATETIME) <= @EndDate) 
         THEN 366.0 
         ELSE 365.0 
         END 
        ELSE 
         CASE WHEN ISDATE(CAST(YEAR(@EndDate) AS CHAR(4)) + '0229') = 1 
         THEN 
          CASE WHEN (@StartDate <= cast('2/29/' + cast(YEAR(@EndDate) AS CHAR(4)) AS DATETIME) AND cast('2/29/' + cast(YEAR(@EndDate) AS CHAR(4)) AS DATETIME) <= @EndDate) 
          THEN 366.0 
          ELSE 365.0 
          END 
         ELSE 365.0 
         END 
        END 
       END 
      END 
     ELSE 
      ((@nbYears * 365.0) + 
       (
        SELECT COUNT(*) FROM 
        (
         SELECT (ROW_NUMBER() OVER(ORDER BY TABLE_NAME ASC) - 1) * 4 + 1900 AS [YEAR] 
         FROM INFORMATION_SCHEMA.COLUMNS 
        ) yr 
        WHERE [YEAR] BETWEEN YEAR(@StartDate) AND YEAR(@EndDate) 
       ) 
      )/@nbYears 
     END 
    RETURN @YearFrac 
END