MySQL计算用户总驾驶时长报错1292:截断不正确时间值
解决MySQL中计算驾驶总时长触发1292截断错误的问题
问题根源
你遇到的Error Code: 1292. Truncated incorrect time value: '3300971'错误,核心原因是MySQL的SEC_TO_TIME()函数有个隐藏限制:它返回的是TIME类型,而TIME类型的取值范围仅为-838:59:59到838:59:59(对应秒数是-3020399到3020399)。
你的计算结果3300971秒已经远超这个范围,这时SEC_TO_TIME()会生成一个无效的TIME值,MySQL在尝试把这个无效值存入VARCHAR字段时,就会触发截断报错。之前代码能正常运行,应该是当时所有用户的总驾驶时长都没超过838小时,随着数据积累才触发了这个问题。
两种可行解决方案
方案1:存储总秒数,查询时格式化
这种方式更灵活,适合后续做其他时长计算:
- 先修改
super_users表的total_drive_time字段类型为INT(用来存储总秒数):
ALTER TABLE super_users MODIFY COLUMN total_drive_time INT;
- 执行UPDATE语句直接存入总秒数:
UPDATE super_users SET total_drive_time = ( SELECT SUM(TIME_TO_SEC(TIMEDIFF(drive_end_time, drive_start_time))) FROM drive_data_final WHERE id = super_users.id );
- 需要展示可读时长时,用自定义逻辑格式化:
SELECT id, CONCAT( FLOOR(total_drive_time / 86400), '天 ', FLOOR((total_drive_time % 86400) / 3600), '小时 ', FLOOR((total_drive_time % 3600) / 60), '分钟 ', total_drive_time % 60, '秒' ) AS formatted_drive_time FROM super_users;
方案2:直接生成格式化字符串存入VARCHAR
如果不想修改字段类型,可以在UPDATE时直接拼接成可读的时长字符串:
UPDATE super_users SET total_drive_time = ( SELECT CONCAT( FLOOR(SUM(TIME_TO_SEC(TIMEDIFF(drive_end_time, drive_start_time))) / 86400), '天 ', FLOOR((SUM(TIME_TO_SEC(TIMEDIFF(drive_end_time, drive_start_time))) % 86400) / 3600), '小时 ', FLOOR((SUM(TIME_TO_SEC(TIMEDIFF(drive_end_time, drive_start_time))) % 3600) / 60), '分钟 ', SUM(TIME_TO_SEC(TIMEDIFF(drive_end_time, drive_start_time))) % 60, '秒' ) FROM drive_data_final WHERE id = super_users.id );
补充说明
你之前拆分代码时,移除SEC_TO_TIME能正常运行,是因为此时存储的是纯数字秒数(字符串形式),没有触发TIME类型的校验;而单独执行SELECT SEC_TO_TIME(total_drive_time)时,虽然同样会生成无效TIME值,但SELECT语句不会强制校验存储,只是返回警告(你可能没注意到警告),而UPDATE语句会严格校验要存入的值,所以触发了报错。
内容的提问来源于stack exchange,提问作者ssskay
相关产品推荐
相关产品推荐

