2016-04-09 79 views
1

我需要在某種程度上兩個日期(DateFromDateTo)之間來計算年,月,日格式的年齡是:總和的兩個日期之間的年齡在年月日格式

  • 如果一個月的一天DateFrom是第一個然後把它作爲一個整月
  • 如果DateFrom中的月份不是第一個,則計數天數直到月底。

實施例:

  • DateFrom = '2010-02-0 ',DateTo = '2011-03-11',年齡= 1年,1月11
  • DateFrom = '2010-02-0 ',DateTo = '2011-03-11',年齡= 1年,1月8

計算年齡後,我需要總結年齡假設該月爲30天 - 在上面的例子中,我預計結果:2年,2個月,19天。

回答

1

所以基本上,因爲這個自定義的日期數學,你需要實現自己的函數來獲得所需的結果。

請參見下面的TSQL

CREATE FUNCTION dbo.getDateSum(@d1 varchar(100), @d2 varchar(100)) 
RETURNS varchar(100) 
WITH EXECUTE AS CALLER 
AS 
BEGIN 
    DECLARE @y int, @m int, @d int 
    Select 
     @d1= REPLACE(REPLACE(REPLACE(@d1,' years, ', '-'),' months, ','-'),' days',''), 
     @d2= REPLACE(REPLACE(REPLACE(@d2,' years, ', '-'),' months, ','-'),' days','') 
    Select 
     @y= CAST(LEFT(@d1,CHARINDEX('-',@d1)-1) AS INT)+CAST(LEFT(@d2,CHARINDEX('-',@d2)-1) AS INT), 
     @m= CAST(SUBSTRING(@d1,CHARINDEX('-',@d1)+1,LEN(@d1)-CHARINDEX('-',REVERSE(@d1))-CHARINDEX('-',@d1))AS INT)+CAST(SUBSTRING(@d2,CHARINDEX('-',@d2)+1,LEN(@d2)-CHARINDEX('-',REVERSE(@d2))-CHARINDEX('-',@d2)) AS INT), 
     @d= CAST(LEFT(REVERSE(@d1),CHARINDEX('-',REVERSE(@d1))-1)AS INT)+CAST(LEFT(REVERSE(@d2),CHARINDEX('-',REVERSE(@d2))-1) AS INT) 

    IF(@d>30) 
    BEGIN 
     SET @[email protected]%30 
     SET @[email protected]+CAST(@d/30 as INT) 
    END 
    IF(@m>30) 
    BEGIN 
     SET @[email protected]%12 
     SET @[email protected]+CAST(@m/12 as INT) 
    END 

    RETURN (cast(@y as varchar)+ ' years, ' + cast(@m as varchar) +' months, '+ cast(@d as varchar) + ' days'); 
END 
go 


CREATE FUNCTION dbo.getDateDiff(@df date, @dt date) 
RETURNS varchar(100) 
WITH EXECUTE AS CALLER 
AS 
BEGIN 
    declare @y int, @m int, @d int 


    Select @y= YEAR(@dt)- YEAR(@df),@m= MONTH(@dt)- MONTH(@df),@d=CASE WHEN DAY(@df)=1 THEN DAY(@dt)- DAY(@df)+1 ELSE DAY(@dt)- DAY(@df) -1 END 
    If (@d<0) 
    BEGIN 
     Set @[email protected] 
     set @[email protected] + DATEDIFF(d, @dt, EOMONTH(@dt)) 
    END 
    IF(@m<0) 
    BEGIN 
     Set @[email protected] 
     Set @[email protected]+ 12 
    END 

    RETURN (cast(@y as varchar)+ ' years, ' + cast(@m as varchar) +' months, '+ cast(@d as varchar) + ' days') 
END 

go 

SELECT dbo.getDateSum(dbo.getDateDiff('2010-02-01','2011-03-11'),dbo.getDateDiff('2010-02-02', '2011-03-11')) 
go 
+0

很多,非常感謝! getDateDiff完美工作,但是,我需要getDateSum函數來總結許多行 - 有時候2有時候是20(我很抱歉沒有在開始時說明它,你能幫助修改代碼嗎? –

1

我的假設是,你必須有一個包含「DateFrom」和「DateTo」列的表,所以查詢將是這樣的:

DECLARE @TotalDiffInDays int = (SELECT AVG(DATEDIFF(DAY, DateFrom, DateTo)) AS [TotalDays] FROM #t) 
SELECT @TotalDiffInDays 
DECLARE @DaysInMonth int = 30; 
DECLARE @DaysInYear int = 365; 

SELECT 
    @TotalDiffInDays/365 AS AvgYearsDiff, 
    (@TotalDiffInDays/@DaysInMonth - @TotalDiffInDays/@DaysInYear * 12) AS AvgMonthsDiff, 
    @TotalDiffInDays - ((@TotalDiffInDays/365) * @DaysInYear + (@TotalDiffInDays/@DaysInMonth - @TotalDiffInDays/@DaysInYear * 12) * @DaysInMonth) AS AvgDaysDiff 

請注意,在這種情況下,我使用INT司得到正確的數字。

此外,如果你只是想在你上面desribed您可以使用此查詢的日期格式的區別:

SELECT 
    DATEDIFF(YEAR, DateFrom, DateTo) AS [Years], 
    -- Add year diff to get corret months diff 
    DATEDIFF(MONTH, DATEADD(YEAR, DATEDIFF(YEAR, DateFrom, DateTo), DateFrom), DateTo) AS [Months], 
    -- Add months diff to get correct days diff 
    DATEDIFF(DAY, DATEADD(MONTH, DATEDIFF(MONTH, DateFrom, DateTo), DateFrom), DateTo) AS [Days] 
FROM #t 

我希望這將有助於。

是的,只是忘了你的規則的第一天,而不是第一天的日期,你可以很容易地修改這些查詢,添加DATEPART(DAY,your_date)函數來檢查它是否是該月的第一個日期並執行DETEADD()應用此邏輯或在AVG之前只添加1的值。

相關問題