date_sub必须指定合法日期和带单位的interval表达式,如date_sub('2024-05-10', interval 7 day);禁止裸数字或非法日期格式;避免在where中对字段使用date_sub以免失效索引。

DATE_SUB 用法:必须指定日期和时间间隔
DATE_SUB 不是简单减个数字,它要求两个明确参数:一个合法日期值(DATE、DATETIME 或字符串格式的日期),以及一个用 INTERVAL 构造的时间表达式。写成 DATE_SUB('2024-05-10', 7) 会直接报错 —— MySQL 完全不接受裸数字作为第二个参数。
正确写法必须带单位:
DATE_SUB('2024-05-10', INTERVAL 7 DAY)DATE_SUB(NOW(), INTERVAL 30 DAY)DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
常见错误:字符串日期格式不合法或时区干扰
传入的日期字符串必须符合 YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS 格式。像 '10/05/2024' 或 '2024/5/10' 会被当成非法日期,DATE_SUB 返回 NULL,且不报错 —— 这容易被忽略,导致后续逻辑出错。
另外注意:NOW() 返回的是服务器当前时区的时间,如果应用跨时区部署,而你期望按 UTC 计算,得先转时区:
- 用
CONVERT_TZ(NOW(), '+00:00', @@session.time_zone)调整基准 - 或统一在应用层处理时区,数据库只存 UTC 值
和 DATE_ADD 对比:负数不能替代 INTERVAL
有人想偷懒写 DATE_ADD('2024-05-10', INTERVAL -7 DAY),这确实等价于 DATE_SUB('2024-05-10', INTERVAL 7 DAY),语法上合法。但别反过来用负数套 DATE_SUB,比如 DATE_SUB('2024-05-10', INTERVAL -7 DAY) —— 虽然 MySQL 不报错,但语义混乱,可读性差,团队协作中容易引发误解。
更关键的是:某些旧版本 MySQL(如 5.5)对负 INTERVAL 在 DATE_SUB 中支持不稳定,建议坚持「正向减」原则。
性能与索引:别在 WHERE 中对字段用 DATE_SUB
写 WHERE order_date > DATE_SUB(NOW(), INTERVAL 30 DAY) 是安全的,因为右侧是常量表达式,优化器能估算范围。
但写成 WHERE DATE_SUB(order_date, INTERVAL 7 DAY) > '2024-01-01' 就糟了 —— 这会让 order_date 列无法走索引,全表扫描风险高。应改写为:
WHERE order_date > DATE_ADD('2024-01-01', INTERVAL 7 DAY)- 或更清晰地:把计算移到右边,保持左边是纯列引用
日期函数套在字段上,基本等于主动放弃索引。这点在数据量稍大时立刻暴露。










