INTERVAL 是 MySQL 日期算术中的关键词而非函数,必须配合 + 或 - 使用,如 DATE + INTERVAL 1 DAY;单位须大写且严格匹配(如 DAY、MONTH),小写或复数会报错;其行为与 DATE_ADD/DATE_SUB 等价,但需注意跨月/年时的自动归整逻辑。

MySQL里用INTERVAL做日期加减,本质是语法糖,不是函数
直接说结论:INTERVAL 本身不是函数,而是 MySQL 日期算术中配合 + 或 - 使用的关键词。写成 DATE + INTERVAL 1 DAY 才合法,单独写 INTERVAL 1 DAY 会报错 ERROR 1064。
它和标准 SQL 的 DATEADD 或 PostgreSQL 的 INTERVAL '1 day' 表达逻辑类似,但语法更紧凑。关键在于:必须跟在日期值之后、运算符之后,且单位必须大写(如 DAY、MONTH),小写或拼错(如 days)会触发 ERROR 1055 或静默截断。
-
NOW() + INTERVAL 7 DAY→ 下周此刻 -
CURDATE() - INTERVAL 1 MONTH→ 上个月第一天(注意:不是自然月减法,2024-03-31 减 1 MONTH 得到 2024-02-29,不是 2024-02-31) -
'2023-01-01' + INTERVAL '2-3' YEAR_MONTH→ 支持复合单位,等价于加 2 年 3 个月
哪些单位可用?大小写和拼写必须严格匹配
MySQL 支持的 INTERVAL 单位有固定列表,不支持自定义或缩写。常见有效单位包括:SECOND、MINUTE、HOUR、DAY、WEEK、MONTH、QUARTER、YEAR、YEAR_MONTH、DAY_HOUR、DAY_MINUTE、DAY_SECOND、HOUR_MINUTE、HOUR_SECOND、MINUTE_SECOND。
容易踩的坑:
- 写成
day(小写)→ 报错Unknown or incorrect time value - 写成
DAYS(复数)→ 被忽略或报错,MySQL 不认复数形式 - 用
WEEK时,MySQL 按 7 天算,不考虑周几起始(即MONDAY或SUNDAY设置不影响结果) -
MONTH和YEAR是“日历单位”,不是固定秒数,所以'2024-01-31' + INTERVAL 1 MONTH得到'2024-02-29',不是'2024-02-31'(无效日期自动归整)
和 DATE_ADD / DATE_SUB 比,选哪个?
DATE_ADD(date, INTERVAL expr unit) 和 date + INTERVAL expr unit 功能完全等价;同理 DATE_SUB(date, INTERVAL expr unit) ≡ date - INTERVAL expr unit。性能无差异,解析开销一致。
选择依据实际可读性与团队习惯:
- 简单场景(如
+ INTERVAL 1 DAY)推荐运算符写法,更紧凑 - 复杂嵌套(如
DATE_ADD(DATE_SUB(NOW(), INTERVAL 1 HOUR), INTERVAL 30 MINUTE))建议统一用DATE_ADD/DATE_SUB,避免括号混乱 - 涉及变量或表达式时,运算符写法更易出错:例如
@d + INTERVAL @n DAY要求@n是整数,若为字符串或 NULL,结果可能为NULL且无提示
跨月/跨年计算的隐式归整行为必须预判
MySQL 对超出范围的日期会自动“归整”而非报错。这是最常被忽略的点,直接影响业务逻辑判断。
例如:
-
'2023-01-31' + INTERVAL 1 MONTH→'2023-02-28'(非'2023-03-03') -
'2023-01-31' + INTERVAL 1 YEAR→'2024-01-31'(正常) -
'2024-02-29' + INTERVAL 1 YEAR→'2025-02-28'(2025 年不是闰年,自动退到 2 月最后一天)
如果你需要“取当月最后一天”这类逻辑,不能依赖 INTERVAL 归整,而应显式用 LAST_DAY() 配合,比如:LAST_DAY(DATE_ADD('2023-01-15', INTERVAL 1 MONTH))。











