【问题标题】:Get difference in years between two dates in MySQL as an integer以整数形式获取 MySQL 中两个日期之间的年差
【发布时间】:2021-07-01 00:41:30
【问题描述】:

我正在尝试计算一个人在数据库中的年龄。
让我们假设有这个简单的表:

student(id, birth_date);

其中 id 是主键(确实该表更复杂,但我已对其进行了简化)。
我想知道一个人有多少岁:

select id, datediff(curdate(),birth_date) 
from student

但它以天为单位返回结果,而不是以年为单位。我可以将其除以 365:

select id, datediff(curdate(),birth_date) / 365
from student

但它返回一个浮点值,我想要一个整数。
所以我可以计算年份:

select id, year(curdate())-year(birth_date) 
from student

但是有一个问题:比如现在是五月,如果一个人战争出生于 1970 年 6 月,他还有 31 岁而不是 32,但表达式返回 32。
我无法摆脱这个问题,有人可以帮助我吗?

【问题讨论】:

  • 哈,我需要计算我数据库中学生的年龄,而你几乎问了我的确切问题...... 6 年前。谢谢! Stack Overflow 很棒。
  • 请考虑更改接受的答案。因为接受的答案至少可以说是不准确的。
  • @LeeTaylor 你能详细说明一下吗?
  • @RamyAlZuhouri 我相信您可以更改接受的答案。 Scott Bonner 的答案不正确,因为它没有考虑闰年(见第一条评论)更好的答案是得票最多的答案(这确实考虑了闰年)。

标签: mysql


【解决方案1】:

我没有足够的声誉来对 Rat-a-tat-a-tat Ratatouille 的答案添加评论以改进他的代码。这是更好的 SQL 查询:

SELECT IFNULL(TIMESTAMPDIFF(YEAR, birthdate, CURDATE()), YEAR(CURDATE()) - YEAR(birthdate)) AS age

这样更好,因为有时“birthdate”可能只包含出生年份,而日期和月份为 0。如果 TIMESTAMPDIFF() 返回 NULL,我们可以通过从出生年份减去当前年份来找到粗略的年龄。

【讨论】:

    【解决方案2】:

    即使考虑到闰年,这也有效!

    select floor((cast(date_format('2016-02-29','%Y%m%d') as int) - cast(date_format('1966-03-01','%Y%m%d') as int)/10000);
    

    请务必保留floor(),因为不需要小数

    【讨论】:

      【解决方案3】:

      对于遇到此问题的任何人:

      另一种方法是:

      SELECT TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) AS difference FROM student
      

      对于月份的差异,将YEAR 替换为MONTH,对于天数,将YEAR 替换为DAY

      希望有帮助!

      【讨论】:

      • 同上coolscitist - 这看起来是最简单,最优雅的答案。
      • 同意。最准确。
      • 这里是TIMESTAMPDIFF的官方文档:dev.mysql.com/doc/refman/5.6/en/…
      • 简洁准确:)
      【解决方案4】:

      我建议这样做:

      DATE_FORMAT(NOW(),"%Y")
         -DATE_FORMAT(BirthDate,'%Y')
         -(
           IF(
            DATE_FORMAT(NOW(),"%m-%d") < DATE_FORMAT(BrthDate,'%m-%d'),
            1,
            0
           )
          ) as Age
      

      这应该非常适合闰年;-)

      【讨论】:

        【解决方案5】:

        接受的答案几乎是正确的,但可能导致错误的结果。

        事实上,/ 365 没有考虑闰年,如果比较与生日具有相同日期和月份的日期,可能会导致错误的结果。

        为了更准确,您必须将其除以 4 年的平均天数,即 (365 * 4) + 1(每 4 年闰年)=> 365.25

        你会更准确:

        select id, floor(datediff(curdate(),birth_date) / 365.25) from student
        

        针对我的一个项目进行了测试,它正在运行。

        【讨论】:

        • 不是 datediff(curdate(),birth_date 转换为浮点数吗?
        • 我不能确定,但​​我测试了它,/365 返回的结果与此处所示的 ` / 365.25` 不同(错误)。
        • 是的,但我不应该使用像 floor 这样的函数来削减结果吗?我可以得到一个非整数的年龄。
        • 这里我不确定。 floor 返回 BigInt,而不是浮点值。 datediff 返回一个整数,除以浮点数,但四舍五入到较低的整数。
        • 这还是不太对。闰年不是每 4 年,而是每 4 年,除了每 100 年,除了每 1000 年。1900 年不是闰年。 2000 是。这将发生工作,因为 2000 年是闰年,大多数生日计算将跨越 2000 年,但跨越 1900 年或 2100 年时它会偏离一天。select floor(datediff("2117-03-19", "2075-03-19") / 365.25) 说41,应该是42。你不能除以天数来得到年,即使使用365.242222也不行。你必须做数学。
        【解决方案6】:

        您可以使用它来获取整数值。

        select id, CAST(datediff(curdate(),birth_date) / 365 as int)
        from student
        

        如果你想了解CONVERT()CAST() here is the link.

        【讨论】:

          【解决方案7】:

          试试:

          SELECT 
            DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birth_date)), '%Y')+0
            AS age FROM student;
          

          【讨论】:

          • 这可以简化为SELECT YEAR(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS("1975-04-20"))); 并且正确处理闰年。
          • 它是否正确处理闰年?关于实际日期的信息在 TO_DAYS 函数中丢失了,我看不出 FROM_DAYS 将如何恢复并解释确切的闰年@elias
          【解决方案8】:

          为什么不对第二种方法的输出使用 MySQL 的 FLOOR() 函数?任何分数都将被删除,从而为您提供所需的结果。

          【讨论】:

            【解决方案9】:
            select id, floor(datediff(curdate(),birth_date) / 365)
            from student
            

            将结果设置为整数怎么样?

            【讨论】:

            • 这不考虑闰年。漂移会变得很明显。 select floor(datediff("2017-03-19", "1975-03-30") / 365); 说 42。那个人 41 岁,休假 11 天。
            • 同意@Schwern
            • 不要使用这个答案。
            • 同意,不要这样做 - 如果没有别的,如果它跨越足够的年份,你将不会考虑闰年,因此你每 4 年就会有一天的时间。
            • 我们如何在上述建议的查询中管理 365 天和 366 天(闰年)?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-01-31
            • 2013-01-05
            • 1970-01-01
            • 2022-10-02
            • 2014-04-07
            相关资源
            最近更新 更多