【问题标题】:Sum of age between two dates in Years Month Days format年月日格式的两个日期之间的年龄总和
【发布时间】:2016-07-30 19:29:07
【问题描述】:

我需要以如下方式计算两个日期(DateFromDateTo)之间的年、月和日格式:

  • 如果DateFrom 中的月份是第 1 天,则将其视为整个月份
  • 如果DateFrom 中的月份不是第一天,则计算天数,直到月底。

例子:

  • DateFrom='2010-02-01', DateTo='2011-03-11', Age= 1 年 1 个月 11
  • DateFrom='2010-02-02', DateTo='2011-03-11', Age= 1 年 1 个月 8

在计算年龄后,我需要将年龄相加,假设该月为 30 天 - 在上面的示例中,我期望结果:2 年,2 个月,19 天。

【问题讨论】:

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


    【解决方案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 除法来获得正确的数字。

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

    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。

    【讨论】:

      【解决方案2】:

      所以基本上自从这个自定义日期数学,你需要实现自己的函数来获得所需的结果。

      查看下面的 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
      

      【讨论】:

      • 非常非常感谢! getDateDiff 工作完美,但是,我需要 getDateSum 函数来汇总许多行 - 有时是 2 有时是 20(很抱歉一开始没有说明。您能帮忙修改代码吗?
      猜你喜欢
      • 2014-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-02
      • 2016-10-23
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      相关资源
      最近更新 更多