【SQL语句】求时间差的函数-timestampdiff() 以及取绝对值(abs)

MySQL 中求时间差的终极神器:TIMESTAMPDIFF() + ABS() 完全实战指南(2025 最新)

在所有数据库中,MySQL 的 TIMESTAMPDIFF() 是最强大、最灵活的时间差计算函数,配合 ABS() 可以轻松实现“求两个时间相差多久(绝对值)”的所有业务场景。

一、核心语法(必须背下来)

TIMESTAMPDIFF(unit, datetime_expr1, datetime_expr2)
  • unit:返回的时间单位(支持 20+ 种)
  • datetime_expr1:开始时间(减数)
  • datetime_expr2:结束时间(被减数)
  • 返回值:datetime_expr2 - datetime_expr1 的整数差值

关键点
谁减谁很重要!
TIMESTAMPDIFF(DAY, '2025-01-01', '2025-01-10') → 返回 9
TIMESTAMPDIFF(DAY, '2025-01-10', '2025-01-01') → 返回 -9

所以要取绝对值必须加 ABS()

二、常用 unit 单位大全(2025 最新)

unit 值含义示例(2025-01-01 10:00:00 到 2025-01-10 15:30:45)
MICROSECOND微秒802845000000
SECOND802845
MINUTE分钟13380
HOUR小时223
DAY9
WEEK1
MONTH0(不足1个月)
QUARTER季度0
YEAR0
SECOND_MICROSECOND‘秒.微秒’ 格式很少用
MINUTE_MICROSECOND‘分.微秒’很少用
其他组合基本不用

最常用DAYHOURMINUTESECOND

三、终极实用 SQL 合集(直接抄到项目)

-- 1. 求两个时间相差多少天(绝对值)
SELECT ABS(TIMESTAMPDIFF(DAY, '2025-01-01', '2025-01-10')) AS days_diff;
-- 结果:9

-- 2. 求两个时间相差多少小时(绝对值)
SELECT ABS(TIMESTAMPDIFF(HOUR, '2025-01-01 10:00:00', '2025-01-10 15:30:45')) AS hours_diff;
-- 结果:223

-- 3. 求两个时间相差多少分钟(绝对值)——最常用!
SELECT ABS(TIMESTAMPDIFF(MINUTE, start_time, end_time)) AS minutes_diff
FROM orders;

-- 4. 求相差多少秒(常用于订单超时判断)
SELECT ABS(TIMESTAMPDIFF(SECOND, create_time, NOW())) AS seconds_from_create
FROM orders 
WHERE ABS(TIMESTAMPDIFF(SECOND, create_time, NOW())) > 1800; -- 超过30分钟

-- 5. 业务场景:订单支付超时判断(推荐写法)
SELECT 
    order_id,
    create_time,
    ABS(TIMESTAMPDIFF(MINUTE, create_time, NOW())) AS wait_minutes
FROM orders 
WHERE status = '待支付'
  AND ABS(TIMESTAMPDIFF(MINUTE, create_time, NOW())) > 15;  -- 超过15分钟未支付

-- 6. 统计用户平均下单间隔(小时)
SELECT 
    user_id,
    AVG(ABS(TIMESTAMPDIFF(HOUR, 
        LAG(create_time, 1) OVER (PARTITION BY user_id ORDER BY create_time),
        create_time
    ))) AS avg_order_interval_hours
FROM orders
GROUP BY user_id;

-- 7. 精确到秒的倒计时(前端展示用)
SELECT 
    activity_id,
    end_time,
    ABS(TIMESTAMPDIFF(SECOND, NOW(), end_time)) AS remain_seconds
FROM activity 
WHERE end_time > NOW();

四、常见坑 & 最佳实践(血泪史)

场景错误写法正确写法说明
取绝对值TIMESTAMPDIFF(…)ABS(TIMESTAMPDIFF(…))防止负数导致逻辑错误
跨月天数计算DATEDIFF()TIMESTAMPDIFF(DAY, …)DATEDIFF 只看日期,不看时间,容易出错
精确到秒的超时判断TIMESTAMPDIFF(MINUTE, …) > 30TIMESTAMPDIFF(SECOND, …) > 1800分钟可能不准(59分59秒 → 59分)
NULL 值处理直接计算COALESCE(start_time, ‘1970-01-01’)防止返回 NULL
性能优化(索引命中)ABS(TIMESTAMPDIFF(…)) > 30TIMESTAMPDIFF(…) > -30 AND TIMESTAMPDIFF(…) < 30ABS 会导致索引失效!

性能杀手

-- 千万不要这样写!索引直接失效
WHERE ABS(TIMESTAMPDIFF(DAY, create_time, NOW())) <= 7

-- 正确写法(走索引)
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)

五、其他数据库对比(2025 版)

数据库求时间差函数是否支持 ABS推荐写法
MySQLTIMESTAMPDIFF() + ABS()最强大、最灵活
PostgreSQLEXTRACT(EPOCH FROM (t2-t1))/单位较麻烦
SQL ServerDATEDIFF(unit, t1, t2) + ABS简单但不支持微秒
Oracle(t2 – t1) * 单位语法最麻烦

结论:用 MySQL 的项目,直接上 ABS(TIMESTAMPDIFF()) 就是最优解!

六、一句话总结(贴工位墙上)

-- 永远记住这一个模板就够了:
SELECT ABS(TIMESTAMPDIFF(单位, 时间1, 时间2)) AS 差值
-- 单位填:SECOND / MINUTE / HOUR / DAY

掌握了 TIMESTAMPDIFF() + ABS(),你就能优雅地解决 95% 的时间差业务需求!

需要我给你一个完整的时间工具函数合集(含倒计时、年龄计算、区间统计)吗?直接说“要”我秒发!

文章已创建 3096

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部