【问题标题】:SQL Server DATEDIFF round up the YEAR difference. How to round it down?SQL Server DATEDIFF 对 YEAR 差值进行四舍五入。如何四舍五入?
【发布时间】:2019-07-02 15:33:13
【问题描述】:

我有一个问题,我尝试使用谷歌搜索,但大多数问题都是关于四舍五入的小时或分钟。

我正在检查用户的生日日期,我有两个相隔 99.3 年的日期。那就是说用户已经99岁了但是这段代码:

DATEDIFF(YEAR, r.BirthDate, ISNULL(@Date,GETDATE()))

返回值 100。有没有办法将值向下舍入?

【问题讨论】:

  • 您使用什么 RDBMS?
  • @MaximFedorov DATEDIFF 和 GETDATE() 驻留在 MS SQL Server 上,因此我断定它是 SQL Server
  • DATEDIFF 计入转换。这是一种完全有效的方法,但可能不是您想要计算来确定年龄的方法。

标签: sql sql-server rounding datediff


【解决方案1】:

您可以使用MONTH 代替YEAR 使用以下解决方案:

DECLARE @currdate AS DATE = '2019-02-08'

-- using YEAR
SELECT DATEDIFF(YEAR, '2000-05-01', ISNULL(@currdate, GETDATE())) -- 19

-- using MONTH
SELECT DATEDIFF(MONTH, '2000-05-01', ISNULL(@currdate, GETDATE())) / 12 -- 18

你也可以ROUND上下:

DECLARE @date DATE = '2019-02-08'

SELECT CAST(ROUND(DATEDIFF(MONTH, '1999-08-01', ISNULL(@date, GETDATE())) / 12.0, 0) AS INT) 
-- 20 (19.5)

SELECT CAST(ROUND(DATEDIFF(MONTH, '1999-09-01', ISNULL(@date, GETDATE())) / 12.0, 0) AS INT) 
-- 19 (19.4)

有没有办法减少天数?

您可以使用天数来舍入天数,但在某些情况下这并不更精确。您可以检查当前日期是否超过出生日期(as @Cato mentioned in comments)。如果出生日期大于当天(同月),您可以减去一个月。

DECLARE @birthday AS DATE = '2000-10-25'
DECLARE @currdate AS DATE = '2100-10-24'
SELECT ((DATEDIFF(MONTH, @birthday, ISNULL(@currdate, GETDATE())) - (CASE WHEN MONTH(@birthday) = MONTH(@currdate) AND DAY(@birthday) > DAY(@currdate) THEN 1 ELSE 0 END)) / 12)
-- 99

【讨论】:

  • 这适用于几个月,但有没有办法将天数舍入?因为有一种可能的情况,如果用户的生日是 10 月 20 日,它会在 10 月 25 日显示用户 99 岁,并且直到 11 月开始才会显示他为 100 岁。
  • 不要走这种路线,总有一些情况下 (days old ) / 365.25 将无法正常工作。我们的技术是找出年份的差异,然后找出这个人是否有生日
【解决方案2】:

你可以使用这个逻辑来得到正确的年龄:

select (case when month(birthdate) * 100 + day(birthdate) >=
                  month(getdate()) * 100 + day(getdate())
             then year(getdate()) - year(birthdate)
             else year(getdate()) - year(birthdate) - 1
        end) as age

这应该是准确的,即使存在闰年。基本上,它查看生日的月份和日期部分,并检查它是在今天还是晚于今天。逻辑使用此信息来确定年龄。

【讨论】:

    【解决方案3】:

    fin 整年的差值(年份 - 出生年份) 这始终是该人在那一年达到的年龄。如果早于他们的生日,请假一年。

    永远不要试图使用日差除以 365.25 或 365 - 由于各种原因,在某些日期,有时会在闰年左右,年龄最终会出现错误

    SELECT YEAR(getdate()) - YEAR(birthdate)  
           - CASE WHEN MONTH(getdate()) < MONTH(birthdate) 
                   OR (DAY(getdate()) < DAY(birthdate) AND MONTH(getdate()) = MONTH(birthdate) )
                THEN
                    1
                ELSE
                    0
                END
    

    【讨论】:

      【解决方案4】:

      Gordon 接受的解决方案很好,但逻辑颠倒了?一般的想法是看当前月份+天是否大于生日的月份+天,如果不是,则从年差中减去一年,因为它还没有达到或超过他们的出生日期。

      SELECT YEAR(GETDATE()) - YEAR(birthdate) 
      - IIF(MONTH(GETDATE()) * 100 + DAY(GETDATE()) >= MONTH(birthdate) * 100 + DAY(birthdate), 0, 1)
      

      【讨论】:

        【解决方案5】:

        解决这个问题的另一种方法(不计算日期差 3 次或更多)是在减去两个值时得到总年数:

        SELECT datediff(YEAR, '1900', DATEADD(d, -1, GETDATE()) - r.BirthDate)
        

        我们从当前日期减去 1 天,因为前一天是 '1/1/1900',这会在间隔中增加一天。

        【讨论】:

          【解决方案6】:

          在雪花中:

          ROUND(DATEDIFF('month', "dateOfBirth", CURRENT_DATE())/12)
          

          你必须按月来做,就好像你选择几年一样,它似乎会四舍五入。

          【讨论】:

            【解决方案7】:

            这就是修复它的方法。

            代替:

            DATEDIFF(YEAR, r.BirthDate, ISNULL(@Date,GETDATE()))
            

            使用这个:

            FLOOR(DATEDIFF(week, r.BirthDate, ISNULL(@Date,GETDATE())) / 52.177457)
            

            这里的an article 证明了这个技巧就像一个魅力。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2023-01-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-11-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多