datediff函数参数顺序和行为因数据库而异:sql server为datediff(unit,start_date,end_date),mysql为datediff(end_date,start_date)且仅支持天数;sql server按“边界穿越”计算,mysql直接相减取整,跨库建议用日期转整数相减。

DATEDIFF 函数的基本用法和参数顺序
DATEDIFF 不是标准 SQL 函数,不同数据库实现差异大,MySQL、SQL Server、PostgreSQL 各自语法不兼容。最常踩的坑是参数顺序反了:SQL Server 是 DATEDIFF(unit, start_date, end_date),而 MySQL 是 DATEDIFF(end_date, start_date)(仅支持天数,且只有两个参数)。别硬背,查文档比记口诀靠谱——执行 SELECT DATEDIFF('2024-01-01', '2024-01-10') 在 MySQL 返回 -9,在 SQL Server 则直接报错“参数个数不匹配”。
MySQL 中 DATEDIFF 只能算天数,别指望它算月或年
MySQL 的 DATEDIFF 严格限定为日期相减,返回整数天数,忽略时间部分。比如 DATEDIFF('2024-02-29 23:59:59', '2024-02-29 00:00:01') 结果仍是 0。想算月份差?得换 TIMESTAMPDIFF(MONTH, start_date, end_date);要小时差?用 TIMESTAMPDIFF(HOUR, ...)。注意:TIMESTAMPDIFF 向下取整,TIMESTAMPDIFF(MONTH, '2023-01-31', '2023-02-28') 返回 0(不足一整月),不是 1。
SQL Server 的 DATEDIFF 单位陷阱:不是日历差,而是“跨越边界次数”
SQL Server 的 DATEDIFF 计算的是指定单位下的“边界穿越次数”,不是自然日历差。例如:DATEDIFF(YEAR, '2023-12-31', '2024-01-01') 返回 1(跨了年份边界),但实际只差 1 天。DATEDIFF(MONTH, '2023-01-31', '2023-02-28') 也返回 1(跨了月边界),哪怕 1 月没 31 日。这种行为在按月分组统计时容易引发逻辑偏差。如果真要算完整月份间隔,得用 DATEFROMPARTS + 手动拆解年月计算,或者改用 DATEDIFF_BIG(SQL Server 2016+)配合更精细的时间单位。
跨数据库可移植方案:用日期相减 + 类型转换最稳妥
如果项目要兼容 MySQL 和 SQL Server,避开 DATEDIFF 是更省心的做法。MySQL 支持日期直接减法:'2024-03-15' - '2024-02-01'(返回天数);SQL Server 支持 CAST 转成 datetime 后用 ABS(DATEDIFF(day, ...))。但真正通用的底线方案是:把日期转成 YYYYMMDD 格式整数再相减,比如 (YEAR(d1)*10000 + MONTH(d1)*100 + DAY(d1)) - (YEAR(d2)*10000 + ...) ——虽不能反映真实天数,但在某些报表场景(如“当月第几天”比较)反而更可控。复杂点在于时区和夏令时,只要数据里没存时区信息,就别碰 TIMESTAMP 级别的差值计算。










