DATEDIFF函数用于计算MySQL中两个日期的天数差,语法为DATEDIFF(end_date, start_date),返回end_date减start_date的整数结果,自动忽略时分秒,参数为NULL或非法格式时返回NULL。

DATEDIFF 函数的基本用法和参数顺序
DATEDIFF 是 MySQL 中专用于计算两个日期之间「天数差」的函数,它只接受两个 DATE 或 DATETIME 类型参数,返回整数。关键点在于:第一个参数是结束日期,第二个是起始日期——顺序反了结果就是负数,但很多人默认“大减小”,实际必须按 DATEDIFF(end_date, start_date) 写。
- 如果字段是
DATETIME类型(比如created_at),DATEDIFF会自动截断时间部分,只比对日期(年-月-日) - 不支持毫秒、小时、分钟级精度;需要小时差请改用
TIMESTAMPDIFF(HOUR, ...) - 传入
NULL会导致整行结果为NULL,建议配合IFNULL或COALESCE处理
SELECT DATEDIFF('2024-05-20', '2024-05-10'); -- 返回 10
SELECT DATEDIFF(order_date, shipped_date) AS days_delay FROM orders;常见错误:WHERE 条件里误用 DATEDIFF 导致索引失效
直接在 WHERE 子句中对日期字段套用 DATEDIFF(比如 WHERE DATEDIFF(NOW(), created_at) > 30)会让 MySQL 无法使用 created_at 上的索引,全表扫描风险高。
- 正确做法是把函数移到右边,让左边保持裸字段:
WHERE created_at - 如果必须动态算天数(比如查“过去 N 天”),优先用
DATE_SUB/DATE_ADD配合变量或参数 -
DATEDIFF在ORDER BY或SELECT列中不影响索引,仅在WHERE左侧裸字段被包装时才失效
跨月/跨年计算是否准确?时区和日期格式有影响吗
DATEDIFF 的计算完全基于日历日期,不涉及时区转换或夏令时逻辑——它只看年、月、日三部分的数值差。例如:
DATEDIFF('2024-01-01', '2023-12-31')→ 返回 1(不是 0)DATEDIFF('2024-03-01', '2024-02-28')→ 返回 2(2024 是闰年,2 月有 29 日,但函数不关心这个,只按日历天数相减)
win可用的mysql指令skill下载安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
字符串必须是标准日期格式(
'YYYY-MM-DD'或'YYYY-MM-DD HH:MM:SS'),否则可能被静默转成 0000-00-00,导致结果异常使用
STR_TO_DATE()转换非标准格式前,务必确认转换结果非NULL,否则DATEDIFF输出为NULL
替代方案:什么时候不该用 DATEDIFF
当你要的不是“日历天数差”,而是“业务有效天数”(比如剔除周末、节假日)或“精确到小时的时间差”,DATEDIFF 就不适用。
- 计算小时差:用
TIMESTAMPDIFF(HOUR, start_time, end_time) - 比较是否超过某段时间:用
DATE_ADD(start_date, INTERVAL 7 DAY) 更直观且可走索引 - 需要兼容 MariaDB 或 PostgreSQL:它们没有
DATEDIFF,得改写为(end_date - start_date)(MySQL 支持,但其他库行为不同)
日期函数看似简单,但顺序、索引、类型隐式转换这三点最容易在上线后暴露问题。尤其在 WHERE 里写 DATEDIFF,压测时 QPS 掉一半才去查执行计划,就晚了。

















