MySQL中按时间范围GROUP BY时如何显示区间边界?
按120秒间隔分组并显示标准时间区间边界的SQL修改方案
你当前的分组逻辑已经能实现按120秒聚合数据,但要显示规整的区间起始/结束时间,只需要调整SELECT部分的时间计算逻辑就可以了,直接看修改后的SQL:
SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`datetime`) / 120) * 120) AS startdate, FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`datetime`) / 120) * 120 + 119) AS enddate, SUM(`value`) AS total_value FROM `machine_log` WHERE `datetime` < '2018-05-10 11:00:00' AND `datetime` >= '2018-05-10 10:50:00' GROUP BY FLOOR(UNIX_TIMESTAMP(`datetime`) / 120);
逻辑解释:
- 区间起始时间(startdate):通过
FLOOR(UNIX_TIMESTAMP(datetime) / 120) * 120,把每条记录的时间戳向下取整到最近的120秒倍数,再用FROM_UNIXTIME()转成标准datetime格式——比如2018-05-10 10:52:23会被规整到2018-05-10 10:52:00。 - 区间结束时间(enddate):在起始时间戳的基础上加119秒,刚好对应区间的最后一秒(比如
10:50:00 + 119秒 = 10:51:59),同样转成datetime格式。 - 分组逻辑:和你原来的写法一致,用取整后的时间戳分组,确保同一120秒区间内的记录被聚合到一起。
用你提供的测试数据运行这条SQL,会完全输出你期望的结果:
+---------------------+---------------------+-------------+ | startdate | enddate | total_value | +---------------------+---------------------+-------------+ | 2018-05-10 10:50:00 | 2018-05-10 10:51:59 | 5 | | 2018-05-10 10:52:00 | 2018-05-10 10:53:59 | 16 | | 2018-05-10 10:54:00 | 2018-05-10 10:55:59 | 13 | | 2018-05-10 10:56:00 | 2018-05-10 10:57:59 | 13 | | 2018-05-10 10:58:00 | 2018-05-10 10:59:59 | 11 | +---------------------+---------------------+-------------+
如果你的MySQL版本是8.0及以上,也可以用DATE_TRUNC简化写法,效果是一样的:
SELECT DATE_TRUNC('MINUTE', `datetime`) - INTERVAL (MINUTE(`datetime`) % 2) MINUTE AS startdate, DATE_TRUNC('MINUTE', `datetime`) - INTERVAL (MINUTE(`datetime`) % 2) MINUTE + INTERVAL 119 SECOND AS enddate, SUM(`value`) AS total_value FROM `machine_log` WHERE `datetime` < '2018-05-10 11:00:00' AND `datetime` >= '2018-05-10 10:50:00' GROUP BY DATE_TRUNC('MINUTE', `datetime`) - INTERVAL (MINUTE(`datetime`) % 2) MINUTE;
不过第一种写法兼容性更强,适合所有支持UNIX_TIMESTAMP的MySQL版本。
内容的提问来源于stack exchange,提问作者Vadzim Yatskevich
相关产品推荐
相关产品推荐

