<p>MySQL的DATE_ADD/DATE_SUB参数顺序严格为日期、INTERVAL、单位,单位须小写;SQL Server的DATEADD顺序为单位、数值、日期;PostgreSQL用+/- INTERVAL操作符,月末逻辑自动修正;跨库迁移需注意隐式行为差异。</p>

MySQL 的 DATE_ADD 和 DATE_SUB 必须严格按顺序写
参数顺序错一个字符就报错,不是警告——DATE_ADD('2024-01-01', INTERVAL 7 DAY) 是对的;DATE_ADD(INTERVAL 7 DAY, '2024-01-01') 直接触发 Incorrect datetime value。日期字段若存的是 VARCHAR,得先用 STR_TO_DATE(date_str, '%Y-%m-%d') 转成合法日期类型,否则加减结果可能为 NULL 或静默出错。单位必须小写:day、month 可行,DAY 或 Day 在严格模式下会失败。
SQL Server 的 DATEADD 参数顺序相反,且缩写不统一
它的写法是 DATEADD(day, 1, '2024-01-01'):单位在前、数值在中、日期在后。别套 MySQL 习惯写成 DATEADD('2024-01-01', day, 1)——语法直接不通过。缩写如 dd、mm 虽可用,但不同版本兼容性差;推荐统一用小写全称:day、month、year。注意 number 参数只认整数,DATEADD(day, 1.7, @dt) 中的 0.7 会被直接截断,不是四舍五入;要算小时级偏移,得换算成秒:DATEADD(second, 1.7 * 24 * 3600, @dt)。
PostgreSQL 不用函数,靠操作符 + 和 - 配合 INTERVAL
它没有 DATE_ADD 或 DATEADD,而是写成 created_at + INTERVAL '7 days' 或 updated_at - INTERVAL '1 hour'。字符串字面量必须带引号,单位也需小写。关键差异在月末逻辑:'2024-01-31'::date + INTERVAL '1 month' 得到 2024-02-29(自动取当月最后一天),而 MySQL 同样写法会先算出 2024-02-31 再被截断为 2024-03-03,结果完全不可比。跨库迁移时,这种隐式修正行为最容易引发数据偏差。
WHERE 条件里日期加减,索引是否失效取决于写法
只要日期字段没被函数包裹,索引就能走:WHERE order_date > DATE_SUB(NOW(), INTERVAL 30 DAY) 安全;但 WHERE DATE_SUB(order_date, INTERVAL 7 DAY) > '2024-01-01' 会让 order_date 上的索引彻底失效。更隐蔽的坑是 NOW() 和 GETDATE():它们每次执行值都变,优化器可能无法准确预估行数,导致执行计划抖动。如果业务真需要“字段加工后比较”,优先考虑加计算列并建索引,而不是每次查询都实时计算。

















