DATEDIFF 是什么
计算两个日期相差的天数。MySQL 的 DATEDIFF(a, b) 等于 a 减 b,只比较日期部分、忽略时间;PostgreSQL 没有同名函数,直接用 date 相减得到整数,而 timestamp 相减得到的是 interval,不是数字。
基本信息
| MySQL 语法 | DATEDIFF(a, b) = a 的日期减 b 的日期,返回整数天数 |
|---|---|
| MySQL 精度 | 只取日期部分,时分秒被忽略 |
| PostgreSQL 日期 | date 减 date 直接返回整数天数 |
| PostgreSQL 时间戳 | timestamp 减 timestamp 返回 interval |
| 取出天数 | PG 用 b::date - a::date,或从 interval 里提取 |
| 常见误用 | 拿 DATEDIFF 计算小时级或分钟级间隔 |
MySQL 写法
MySQL 写法
SELECT DATEDIFF('2024-06-10', '2024-06-01'); -- 9
SELECT DATEDIFF('2024-06-02 00:01', '2024-06-01 23:59'); -- 1:忽略时间,只比日期
SELECT DATEDIFF(end_date, start_date) AS days FROM projects;
-- 需要小时或分钟级精度时换函数
SELECT TIMESTAMPDIFF(HOUR, start_at, end_at) AS hours FROM tasks;PostgreSQL 写法
PostgreSQL 写法
SELECT DATE '2024-06-10' - DATE '2024-06-01'; -- 9(整数)
SELECT (end_ts::date - start_ts::date) AS days FROM projects;
SELECT ts2 - ts1 AS elapsed FROM t; -- interval:'01:00:00'
-- 想从 interval 里取天数
SELECT EXTRACT(DAY FROM (ts2 - ts1)) AS days FROM t;两库对照
| 需求 | MySQL 8 | PostgreSQL |
|---|---|---|
| 日期天数差 | DATEDIFF(a, b) | a - b(date 类型) |
| 时间戳差 | TIMESTAMPDIFF(SECOND, a, b) | b - a(得到 interval) |
| 忽略时间 | DATEDIFF 天然只比日期 | 先转 date 再相减 |
| 结果是数字 | 是 | date 相减是数字;timestamp 相减不是 |
| 小时级精度 | TIMESTAMPDIFF(HOUR, …) | EXTRACT(EPOCH FROM b - a) / 3600 |
| 与今天比较 | DATEDIFF(CURDATE(), col) | CURRENT_DATE - col::date |
典型使用场景
- 计算账期天数、工单处理天数
- 留存分析:注册到首次下单相隔多少天
- 合同与证照到期提醒:距离到期还有多少天
- 超期判定:与今天相减判断是否超过阈值
- 报表口径核对:确认两侧系统算出的天数一致
- 数据校验:出现负天数说明字段顺序或数据本身有误
- 会员权益:从开通日算到今天已过去多少天,用于判断是否过期
- 间隔天数的分布分析:平均发货时效、最长等待天数
只比日期是 DATEDIFF 的特性:'2024-06-01 23:59' 与 '2024-06-02 00:01' 实际只差 2 分钟,DATEDIFF 却返回 1 天。需要真实间隔就用时间戳相减,不要靠天数凑精度。
时区会影响“差几天”:跨时区的两个时间点在不同时区下可能落在不同日期,先统一到业务时区再转日期相减,结果才和业务口径一致。
PostgreSQL 里 timestamp 相减得到的是 interval:直接与整数比较会报类型错误。需要天数时先转成日期,需要秒数时用 EXTRACT(EPOCH FROM …)。