MySQL中是否有方法计算两个日期的月数与天数差值?
必须有啊!在MySQL里我们可以组合几个内置的日期函数来实现你要的效果,完美输出类似1 month 1 day这样的格式。我给你一步步拆解,再结合你的例子来演示:
核心思路
要得到两个日期之间的月数+天数差值,我们需要分两步走:
- 先计算两个日期之间的整月数
- 再计算扣除整月数之后,剩余的天数差
- 最后把这两部分拼接成你想要的字符串格式
基础实现(匹配你的例子)
针对你给出的起始日期2018-01-01和结束日期2018-02-02,可以用下面的SQL语句直接得到结果:
SELECT CONCAT( -- 计算整月数 TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-02'), ' month', -- 处理单数复数(可选,如果你需要严谨的语法) IF(TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-02') != 1, 's', ''), ' ', -- 计算剩余天数:把起始日期加上整月数后,和结束日期算天数差 DATEDIFF('2018-02-02', DATE_ADD('2018-01-01', INTERVAL TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-02') MONTH)), ' day', -- 同样处理天数的单数复数 IF(DATEDIFF('2018-02-02', DATE_ADD('2018-01-01', INTERVAL TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-02') MONTH)) != 1, 's', '') ) AS date_difference;
执行这段SQL后,会返回你期望的结果:1 month 1 day
优化版本(处理边界情况)
如果遇到一些特殊场景,比如两个日期刚好差整月(比如2018-01-31到2018-02-28),或者差多天零月,我们可以优化语句,自动隐藏为0的部分,并且保持语法严谨:
SELECT CONCAT_WS(' ', -- 当月数大于0时才显示月数部分 CASE WHEN month_diff > 0 THEN CONCAT(month_diff, ' month', IF(month_diff != 1, 's', '')) END, -- 当天数大于0时才显示天数部分 CASE WHEN day_diff > 0 THEN CONCAT(day_diff, ' day', IF(day_diff != 1, 's', '')) END ) AS date_difference FROM ( -- 先计算出月数和天数的差值,作为子查询复用 SELECT TIMESTAMPDIFF(MONTH, '2018-01-31', '2018-02-28') AS month_diff, DATEDIFF('2018-02-28', DATE_ADD('2018-01-31', INTERVAL TIMESTAMPDIFF(MONTH, '2018-01-31', '2018-02-28') MONTH)) AS day_diff ) AS diff_calculations;
这个版本执行后,会返回1 month(因为剩余天数为0,自动隐藏);如果是2018-01-01到2018-01-05,则会返回4 days。
关键函数说明
TIMESTAMPDIFF(unit, start, end):用来计算两个日期之间的差值,指定MONTH作为单位就能得到整月数,它会自动处理不同月份的天数差异(比如1月31到2月28算1个月)DATE_ADD(date, INTERVAL expr unit):用来给起始日期加上计算出的整月数,得到一个中间日期DATEDIFF(end, start):计算两个日期之间的天数差CONCAT()/CONCAT_WS():用来拼接字符串,CONCAT_WS会自动忽略空值,适合处理需要隐藏0值的场景
内容的提问来源于stack exchange,提问作者user3292629
相关产品推荐
相关产品推荐

