按小时分组时如何查询bytes_in_use最大值对应的记录
解决方案
要获取每个小时内bytes_in_use值最大的完整记录,你可以根据数据库版本选择以下两种方法:
方法一:使用窗口函数(推荐,适用于MySQL 8.0+、PostgreSQL、SQL Server等)
利用ROW_NUMBER()窗口函数按日期+小时分组,在每个组内按bytes_in_use降序排序,取排名第一的记录:
WITH hourly_max AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY DATE(created_at), HOUR(created_at) ORDER BY bytes_in_use DESC ) AS rn FROM datastore_usage WHERE datastore_id = 1 ) SELECT * FROM hourly_max WHERE rn = 1 ORDER BY created_at DESC LIMIT 10;
PARTITION BY DATE(created_at), HOUR(created_at):确保不同日期的同一小时(比如10月1日10点和10月2日10点)被分成独立的组ROW_NUMBER():在每个小时组内,给记录按bytes_in_use从大到小排名,最大值的记录排名为1- 如果同一个小时内有多个记录的
bytes_in_use同为最大值,且你想返回所有这些记录,可以把ROW_NUMBER()换成RANK()
方法二:子查询关联(适用于不支持窗口函数的旧版本数据库,如MySQL 5.7及以前)
先通过子查询找出每个小时的bytes_in_use最大值,再关联原表获取对应的完整记录:
SELECT d.* FROM datastore_usage d JOIN ( SELECT DATE(created_at) AS usage_date, HOUR(created_at) AS usage_hour, MAX(bytes_in_use) AS max_bytes FROM datastore_usage WHERE datastore_id = 1 GROUP BY usage_date, usage_hour ) m ON DATE(d.created_at) = m.usage_date AND HOUR(d.created_at) = m.usage_hour AND d.bytes_in_use = m.max_bytes WHERE d.datastore_id = 1 ORDER BY d.created_at DESC LIMIT 10;
这种方法会返回同一小时内所有bytes_in_use等于最大值的记录,如果只需要一条,可以添加额外排序条件(比如按created_at降序取第一条)。
为什么你之前的查询有问题?
你之前直接GROUP BY HOUR(created_at)再SELECT *属于非标准SQL写法(MySQL宽松模式下允许但结果不可控):返回的id、created_at等字段是该小时组内的任意一条记录,和MAX(bytes_in_use)没有关联,因此无法得到正确的完整记录。
内容的提问来源于stack exchange,提问作者michael holstein
相关产品推荐
相关产品推荐

