年月日格式

时间:2016-04-09 14:32:22

标签: sql sql-server tsql sql-server-2012

我需要以下列方式计算两个日期(DateFromDateTo)之间的年,月,日格式的年龄:

  • 如果DateFrom中的某一天是第1天,则将其作为整月使用
  • 如果DateFrom中的某一天不是第一天,则计算直到月底的天数。

示例:

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

在计算年龄后,我需要将年龄相加,假设月份是30天 - 在上面的例子中,我预计结果:2年,2个月,19天。

2 个答案:

答案 0 :(得分:2)

我的假设是你有一个包含“ 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 除法来获取正确的数字。

此外,如果您只想以上述格式获取日期差异,可以使用此查询:

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。

答案 1 :(得分: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 @d=@d%30
        SET @m=@m+CAST(@d/30 as INT)
    END
    IF(@m>30)
    BEGIN
        SET @m=@m%12
        SET @y=@y+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 @m=@m-1
        set @d=@d + DATEDIFF(d, @dt, EOMONTH(@dt))
    END
    IF(@m<0)
    BEGIN
        Set @y=@y-1
        Set @m=@m+ 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