2016-07-09 163 views
3

我有一個表叫日期,需要計算的年,月,日爲截止日期

Opendate | Closedate 
------------+--------------- 
2015-07-09 | 2016-08-10 

我期待輸出一樣,

opendate | closedate | diff  
------------+---------------+---------------------- 
2015-07-09 | 2016-08-10 | 1year 1month 1day 
2015-07-09 | 2016-03-01 | 8 months 20 days 
2015-07-09 | 2015-07-11 | 2 days 

但是當我運行此查詢:

SELECT opendate, 
     closedate, 
     Datediff(year, opendate, closedate) AS years, 
     Datediff(month, opendate, closedate) AS months, 
     Datediff(day, opendate, closedate) AS days 
FROM dates 

這是給我一個輸出類似,

opendate | closedate | years | months | days  
------------+---------------+-------+--------+--------- 
2015-07-09 | 2016-08-10 | 1 | 13 | 397 

我們如何計算一年一個月零1天

+0

當'closedate'是'2016-03-01' –

+0

@Prdp應該是8個月和20天 –

+0

因此,當結束日期是'2015-07-11'時,結果應該是'2天' –

回答

4

您可以使用Stacked CTE逐一查找下一年,月份和日期。

說明

查詢低於第一找出DATEDIFF年Opendate裏和closedate和檢查,如果所得到的日期比closedate更大。如果是,則實際年差是Y-1的DATEDIFF。使用這個新的日期,並使用相同的邏輯獲取DATEDIFF個月,然後在幾天內獲得差異。

Online Example

查詢

WITH D(Opendate,Closedate)AS 
(
SELECT CAST('2015-07-09' AS DATE),CAST('2016-08-10' AS DATE) 
UNION ALL 
SELECT CAST('2015-07-09' AS DATE),CAST('2016-03-01' AS DATE) 
UNION ALL 
SELECT CAST('2015-07-09' AS DATE),CAST('2015-07-11' AS DATE) 

),Y AS 
(
SELECT Opendate,Closedate, 
    CASE 
    WHEN DATEADD(YEAR,DATEDIFF(YEAR,Opendate,Closedate),Opendate) > Closedate 
    THEN DATEDIFF(YEAR,Opendate,Closedate) - 1 
    ELSE DATEDIFF(YEAR,Opendate,Closedate) 
    END Years 
FROM D 
), YDate as 
(
SELECT Opendate,Closedate,Years,DATEADD(YEAR,Years,Opendate) as Newopendate 
FROM Y 
),M AS 
(
SELECT Opendate,Closedate,Years,Newopendate, 
CASE WHEN DATEADD(MONTH,DATEDIFF(MONTH,Newopendate,Closedate),Newopendate) > Closedate 
THEN DATEDIFF(MONTH,Newopendate,Closedate) - 1 
ELSE DATEDIFF(MONTH,Newopendate,Closedate) 
END Months 
FROM YDate 
) 
SELECT Opendate,Closedate,Years,Months,DATEDIFF(Day,DATEADD(MONTH,Months,Newopendate),Closedate) as days 
FROM M 

結果

Opendate Closedate Years Months days 
09-07-2015 00:00 10-08-2016 00:00 1 1 1 
09-07-2015 00:00 01-03-2016 00:00 0 7 21 
09-07-2015 00:00 11-07-2015 00:00 0 0 2 
1
SELECT opendate, 
     closedate, 
     ((Datediff(year, opendate, closedate) + 'years')+ 
     ((Datediff(month, opendate, closedate) - 
      12 * Datediff(year, opendate, closedate)) + 'months') + 
     (Datediff(day, opendate, closedate) - 
     (Datediff(year, opendate, closedate) * 365 - 
     (Datediff(month, opendate, closedate) * 12))) + 'days' 

FROM dates 

的邏輯是您連接這些年來,然後扣除一年的月沒有。同樣可以扣除天數

+0

消息245,級別16,狀態1,行11 將varchar值「years」轉換爲數據類型int時轉換失敗。 –

1

創建一個功能如下

CREATE FUNCTION dbo.GetYearMonthDays 
    (
     @FromDate DATETIME 
    ) 
    RETURNS NVARCHAR(100) 
    AS 
    BEGIN 
     DECLARE @date datetime, @tmpdate datetime, @years int, @months int, @days int 
     SELECT @date [email protected] 

    SELECT @tmpdate = @date 

    SELECT @years = DATEDIFF(yy, @tmpdate, GETDATE()) - CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END 
    SELECT @tmpdate = DATEADD(yy, @years, @tmpdate) 
    SELECT @months = DATEDIFF(m, @tmpdate, GETDATE()) - CASE WHEN DAY(@date) > DAY(GETDATE()) THEN 1 ELSE 0 END 
    SELECT @tmpdate = DATEADD(m, @months, @tmpdate) 
    SELECT @days = DATEDIFF(d, @tmpdate, GETDATE()) 

     RETURN CONVERT(varchar(10), @years) +' Years ' + CONVERT(varchar(10), @months) + ' Month ' + CONVERT(varchar(10), @days) + ' Days' 
    END 
    GO 

和使用如下

SELECT opendate, 
     closedate,dbo.GetYearMonthDays(closedate) 
FROM dates 

這會給你你想要的東西。