datediff 行为因数据库而异:mysql 仅支持 date 类型且顺序敏感;sql server 按边界跨越计数;postgresql 用减法更直观,需注意时区、null 和版本差异。

DATEDIFF 是多数 SQL 方言中计算两个日期差的主力函数,但它的行为在不同数据库里差异很大——直接套用容易得出错误结果。
MySQL 的 DATEDIFF 只接受 DATE 类型,且固定以第一个参数减第二个参数
MySQL 的 DATEDIFF 严格要求两个参数都是 DATE(不带时间部分),自动截断 DATETIME 的时分秒。它只返回「天数整数」,且顺序不能反:`DATEDIFF(end_date, start_date)` 才是正向天数。
- 如果传入
DATETIME值(如'2024-05-01 14:30:00'),会被隐式转为'2024-05-01',丢失时间精度 - 写成
DATEDIFF('2024-05-01', '2024-04-28')得到3;反过来写就是-3 - 想算带时间的精确天数差?得改用
TIMESTAMPDIFF(DAY, start, end)或手动除以 86400 秒
SQL Server 的 DATEDIFF 支持单位指定,但默认按「边界跨越」计数
SQL Server 的 DATEDIFF 第一个参数是单位(DAY、HOUR 等),它统计的是「单位边界被跨越的次数」,不是简单的日历天数相减。
-
DATEDIFF(DAY, '2024-04-28 23:59:59', '2024-04-29 00:00:01')返回1—— 跨过了午夜线 -
DATEDIFF(DAY, '2024-04-28 00:00:00', '2024-04-28 23:59:59')返回0—— 同一天内,没跨日 - 要严格按 24 小时制算天数?得用
DATEDIFF(SECOND, ...)/86400.0再ROUND或FLOOR
PostgreSQL 没有 DATEDIFF,直接用减法更直观
PostgreSQL 中两个 DATE 相减得整数天数,两个 TIMESTAMP 相减得 INTERVAL,再用 EXTRACT(DAY FROM ...) 或直接 ...::int 转换。
-
'2024-05-01'::DATE - '2024-04-28'::DATE→3 -
'2024-05-01 10:00'::TIMESTAMP - '2024-04-28 16:00'::TIMESTAMP→2 days 18:00:00 -
EXTRACT(EPOCH FROM (end_ts - start_ts))/86400可得带小数的精确天数
最易被忽略的是:日期字段是否含时区、是否为 NULL、以及数据库实际使用的方言版本(比如旧版 MySQL 不支持 TIMESTAMPDIFF)。别只看函数名,先 SELECT VERSION() 或查文档确认行为。











