DATEDIFF函数在不同数据库中行为差异极大,它不总是返回两个日期之间的精确天数差:SQL Server按日边界计算,MySQL强制截断时间,PostgreSQL则无此函数而用减法。

直接说结论:DATEDIFF 函数在不同数据库中行为差异极大,**它不总是返回“两个日期之间的精确天数差”**——尤其在 SQL Server 和 MySQL 中,它默认只比较年/月/日部分,忽略时间精度,容易导致结果偏差 1 天。
SQL Server 的 DATEDIFF 默认按日期边界计算,不是简单相减
SQL Server 的 DATEDIFF(day, @start, @end) 实际计算的是两个时间值跨越的“日边界”数量。比如 '2024-01-01 23:59:59' 到 '2024-01-02 00:00:01',虽然只差 2 秒,DATEDIFF(day, ...) 仍返回 1;而 '2024-01-01 00:00:00' 到 '2024-01-01 23:59:59' 却返回 0。
要得到真正的时间差天数(含小数),得先转成秒再除以 86400:
SELECT DATEDIFF(second, '2024-01-01 12:00:00', '2024-01-02 14:30:00') / 86400.0 AS days
- 用
second或millisecond作为 datepart 参数,避免日边界截断 - 除以
86400.0(带小数点)确保结果为浮点数,保留小数位 - 如果只要整数天且忽略时间部分,才用
day;否则别信它的“天数”结果
MySQL 的 DATEDIFF 只接受 DATE 类型,自动截断时间
MySQL 的 DATEDIFF(enddate, startdate) **强制将输入转为 DATE**,即丢弃所有时间信息。传入 '2024-01-01 23:59:59' 和 '2024-01-02 00:00:01',实际计算的是 DATEDIFF('2024-01-01', '2024-01-02') → 1,但你可能以为该是 0.000023 天。
需要精确天数时,必须改用 TIMESTAMPDIFF 或直接计算秒差:
SELECT TIMESTAMPDIFF(second, '2024-01-01 12:00:00', '2024-01-02 14:30:00') / 86400.0 AS days
-
TIMESTAMPDIFF支持second、microsecond等粒度,且保留时间部分 - 注意参数顺序:MySQL 是
TIMESTAMPDIFF(unit, start, end),和DATEDIFF相反 - 别用
DATEDIFF处理带时间的字段,它根本不管时分秒
PostgreSQL 没有 DATEDIFF,但减法更直观可靠
PostgreSQL 不提供 DATEDIFF 函数,而是直接支持 timestamp - timestamp,结果是 interval 类型。要转成天数(含小数),用 EXTRACT(epoch FROM ...):
SELECT EXTRACT(epoch FROM ('2024-01-02 14:30:00'::timestamp - '2024-01-01 12:00:00'::timestamp)) / 86400.0 AS days-
epoch提取总秒数,再除以86400.0得精确天数 - 如果两个字段是
date类型,相减直接得整数天,无需转换 - 务必显式类型转换(如
::timestamp),避免隐式转换出错
跨数据库写 SQL 时,DATEDIFF 这个名字最危险——它看起来统一,实则逻辑割裂。真正需要“精确天数”时,别依赖函数名,先确认你用的是哪个数据库,再看它对时间部分到底怎么处理。时间字段里那几个小时分钟,往往就是误差来源。

















