如何在MySQL中按每5分钟间隔汇总一天的数据量?

作者站长头像
站长
· 阅读数 12

MySQL语句查询:将1天24小时按每5分钟分成小段,即00:00:00 - 00:04:59 、00:05:00 - 00:09:59 、00:10:00 - 00:14:59 、00:15:00 - 00:19:59 、00:20:00 - 00:24:59 、 ... 23:50:00 - 23:54:59 、23:55:00 - 23:59:59 。


现有一张表,表中有一日期字段,类型为datetime要求按天的维度统计 每个时间段内的数据数量,时间段内没有数据显示为0,其结果固定为288条。

求最简洁效率最高的写法~~

进阶写法,通过修改传参, 可按每10分钟的范围进行统计,这样固定结果就是 144条。

回复
1个回答
avatar
test
2024-06-19

通过一天的努力,这个需求终于搞定,现将实现方案发出来供大家参考。

本需求的难点在于补0。想了好多办法都被否决掉了,最终的方案是新建一张表来存储时间段,虽然不是最佳方案,但是目前可以快速解决这个问题,如果有大神在不建表的情况搞定,膜拜一个。废话不多说,上表

CREATE TABLE `time_intervals` (
  `grouped_time` time DEFAULT NULL
)

很简单吧,就一个字段。接下来给表插入数据,手动输入太慢,代码太麻烦,直接写个存储过程,就可以搞定,上代码:

DELIMITER //  
CREATE PROCEDURE InsertTimeIntervals()  
BEGIN  
    DECLARE currentTime TIME DEFAULT '00:00:00';  
    DECLARE endTime TIME DEFAULT '23:55:00';  
    TRUNCATE  TABLE time_intervals;
    WHILE currentTime <= endTime DO  
        INSERT INTO time_intervals (grouped_time) VALUES (currentTime);  
        SET currentTime = ADDTIME(currentTime, '00:05:00');  
    END WHILE;  
END //  
DELIMITER ;

以上存储过程为每5分钟分割时间段。执行 CALL InsertTimeIntervals();answer image

一共288行

接下来就是写SQL了,为了方便大家阅读和理解,我把SQL先拆分开,一步一步组装,方便大家能理解思路.

第一步:先按每5分钟查出实际数据,这个数据是没有补0的,SQL如下:

SELECT 
    DATE_FORMAT(create_time, '%Y-%m-%d %H:%i') - INTERVAL (MINUTE(create_time) MOD 5) MINUTE AS grouped_time,
    COUNT(*) AS couns
FROM 
    interface_access_frequency 
    WHERE  
      DATE(create_time) = '2024-04-27'
GROUP BY 
    grouped_time;

第二步,使用UNION 链接 grouped_time表,进行补0,SQL如下

(SELECT 
    DATE_FORMAT(DATE_FORMAT(create_time, '%Y-%m-%d %H:%i') - INTERVAL (MINUTE(create_time) MOD 5) MINUTE,'%H:%i') AS grouped_time,
    COUNT(*) AS couns
FROM 
    interface_access_frequency 
    WHERE  
      DATE(create_time) = '2024-04-27'
GROUP BY 
    grouped_time
ORDER BY create_time DESC )
UNION
SELECT  DATE_FORMAT(grouped_time, '%H:%i') AS grouped_time,0 AS couns FROM time_intervals;

但是这样处理后,会有重复记录,所以第三步,再进行一次 GROUP BY ,就可以获得预期的数据了,最终SQL如下:

SELECT grouped_time,MAX(counts) AS counts FROM
((SELECT 
    DATE_FORMAT(DATE_FORMAT(create_time, '%Y-%m-%d %H:%i') - INTERVAL (MINUTE(create_time) MOD 5) MINUTE,'%H:%i') AS grouped_time,
    COUNT(*) AS counts
FROM 
    interface_access_frequency 
    WHERE  
      DATE(create_time) = '2024-04-27'
GROUP BY 
    grouped_time)
UNION
SELECT  DATE_FORMAT(grouped_time, '%H:%i') AS grouped_time,0 AS counts FROM time_intervals) a
 GROUP BY  grouped_time
  ORDER BY grouped_time ASC;

完美。

示例中业务表名为interface_access_frequency,时间字段为create_time,使用时记得修改!

使用阿里云数据库,版本8.0

如有发现错误好着更好解决办法,请留言斧正~~

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容