date_add函数必须严格按date_add(date, interval value unit)顺序传参,unit须全大写单数(如day、month);它自动处理闰年跨月等日历逻辑,但where中对字段用date_add会导致索引失效。

DATE_ADD 用法:参数顺序和单位必须严格匹配
MySQL 的 DATE_ADD 不接受模糊表达,第一个参数必须是日期类型(DATE、DATETIME 或 TIMESTAMP),第二个参数必须是 INTERVAL value unit 形式。常见错误是把天数直接当第二个参数传,比如 DATE_ADD('2024-01-01', 5) —— 这会报错 Incorrect parameter count。
- 正确写法:
DATE_ADD('2024-01-01', INTERVAL 5 DAY) -
unit必须全大写,且只能是预定义单位(DAY、MONTH、YEAR、HOUR等),不能写成days或day - 如果日期字段来自表,比如
order_date,直接套用:DATE_ADD(order_date, INTERVAL 7 DAY)
跨月/跨年计算时 DATE_ADD 会自动进位
DATE_ADD 不是简单加天数,它按日历逻辑处理边界。比如给 2024-01-31 加 1 个月,结果是 2024-02-29(因为 2024 是闰年);加 1 天则得 2024-02-01。这点和直接加 86400 秒的 UNIX 时间戳方式完全不同。
- 加 30 天:
DATE_ADD('2024-01-31', INTERVAL 30 DAY)→2024-03-01 - 加 1 个月:
DATE_ADD('2024-01-31', INTERVAL 1 MONTH)→2024-02-29 - 如果需要“固定加 N 天”语义(不考虑月份长度),就坚持用
DAY;若要“下个月同日”,才用MONTH
在 WHERE 条件中使用 DATE_ADD 要小心索引失效
如果写 WHERE DATE_ADD(created_at, INTERVAL 7 DAY) > NOW(),MySQL 无法走 created_at 上的索引,因为对字段做了函数运算。等价但可走索引的写法是把函数移到右边:
- ❌ 慢查询:
WHERE DATE_ADD(created_at, INTERVAL 7 DAY) > NOW() - ✅ 可索引:
WHERE created_at > DATE_SUB(NOW(), INTERVAL 7 DAY) - 同理,查“7 天前的数据”优先用
DATE_SUB,而不是对字段用DATE_ADD
DATE_ADD 在不同数据库里名字不一样
MySQL 用 DATE_ADD,PostgreSQL 用 current_date + INTERVAL '5 days',SQL Server 用 DATEADD(day, 5, GETDATE())。如果你写的 SQL 要跨数据库运行,别硬套 MySQL 写法——哪怕只是临时查数据,也得先确认当前连接的是哪个引擎。
- MySQL:
DATE_ADD('2024-01-01', INTERVAL 5 DAY) - PostgreSQL:
'2024-01-01'::date + INTERVAL '5 days' - SQLite:
date('2024-01-01', '+5 days') - Oracle:
TO_DATE('2024-01-01', 'YYYY-MM-DD') + 5(直接加数字即加天数)
单位拼写、括号位置、是否支持负数间隔,每个系统都略有差异。上线前最好在目标环境里实测一次。










