timestampdiff(second, start_time, end_time) 返回整秒差,截断微秒部分、不四舍五入;需亚秒精度时应改用 unix_timestamp(end_time) - unix_timestamp(start_time),并确保字段为 datetime(3) 或更高精度。

为什么 TIMESTAMPDIFF 返回的秒数有时不精确
因为 TIMESTAMPDIFF(SECOND, start_time, end_time) 只计算两个时间值的「整秒差」,它会截断微秒部分,不四舍五入。比如 '2024-01-01 10:00:00.999' 和 '2024-01-01 10:00:01.001' 的差值仍是 1 秒,而非 1.002 —— 它压根不处理小数秒。
要真正得到带毫秒/微秒精度的秒差,该用什么
必须绕过 TIMESTAMPDIFF,改用时间转为数值再相减的方式:
-
UNIX_TIMESTAMP()返回从 Unix 纪元起的秒数(带小数,精度取决于 MySQL 版本和字段类型) - 对
DATETIME(6)或TIMESTAMP(6)字段,UNIX_TIMESTAMP()在 MySQL 8.0.28+ 支持微秒级返回值 - 直接相减:
UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)
示例:
SELECT UNIX_TIMESTAMP('2024-01-01 12:34:56.789') - UNIX_TIMESTAMP('2024-01-01 12:34:55.123');
结果是 1.666(单位:秒),保留三位小数。
TIMESTAMPDIFF 的单位参数陷阱
TIMESTAMPDIFF 的第一个参数是单位,但注意:SECOND、MINUTE、HOUR 等只做向下取整计算,且不支持 MICROSECOND 或小数单位。
- 想算微秒差?不能用
TIMESTAMPDIFF(MICROSECOND, ...)—— MySQL 不支持该单位,会报错ER_WRONG_ARGUMENTS -
TIMESTAMPDIFF(SECOND, ...)和TIMESTAMPDIFF(MINUTE, ...)结果都是整数,无法反推毫秒级行为 - 跨天计算时,
TIMESTAMPDIFF对时区敏感:若字段是TIMESTAMP类型,会按系统时区转换后再算;DATETIME则原样比较
实际写 SQL 时怎么选
看需求场景:
- 只要整秒偏差(如统计任务耗时是否超 60 秒),用
TIMESTAMPDIFF(SECOND, t1, t2)最快、最安全 - 需要亚秒级精度(如性能分析、日志打点),必须用
UNIX_TIMESTAMP(t2) - UNIX_TIMESTAMP(t1),并确保字段定义含精度,如DATETIME(3) - 如果字段是字符串,先用
STR_TO_DATE()转成带精度的 datetime,否则UNIX_TIMESTAMP()会丢掉小数部分
真正容易被忽略的是:哪怕你写了 DATETIME(6),如果客户端或驱动默认不传微秒,或者 INSERT 时没显式指定精度,那存储下来就是 .000000 —— 差值再准也没用。











