
本文介绍如何将时间戳列表按每小时区间(如“10-11”“11-12”)分组并统计出现次数,最终生成形如 的键值映射,适用于日志分析、访问量时段统计等场景。
本文介绍如何将时间戳列表按每小时区间(如“10-11”“11-12”)分组并统计出现次数,最终生成形如 `` 的键值映射,适用于日志分析、访问量时段统计等场景。
在实际数据分析中,常需将原始时间戳(如 2023-07-18 10:10:00)归入自然小时区间(例如 10:00–10:59.999 对应区间 "10-11"),并统计各区间内记录数量。注意:这不是简单按 HOUR() 取整分组,而是需构造语义明确的区间标签(如 "10-11"),同时确保逻辑严谨——同一小时内的所有记录必须归属唯一且一致的区间标识。
以下为推荐的 SQL 实现方案(兼容 MySQL 5.7+ 及以上版本):
SELECT CONCAT(HOUR(date_time), '-', HOUR(date_time) + 1) AS hour_range, COUNT(*) AS count FROM your_table GROUP BY HOUR(date_time) ORDER BY HOUR(date_time);
✅ 关键说明:
-
HOUR(date_time)提取时间戳的小时部分(0–23),天然实现“向下取整到整点”,即10:10和10:59均归入HOUR=10; -
CONCAT(HOUR(...), '-', HOUR(...) + 1)动态生成可读区间字符串(如"10-11"),语义清晰,便于后续程序解析或展示; -
GROUP BY HOUR(date_time)确保每个自然小时独立聚合,避免跨日或时区干扰(假设数据已统一为本地时区或 UTC); -
ORDER BY HOUR(...)保证结果按时间顺序排列,提升可读性。
⚠️ 注意事项:
- 若数据跨多天(如含
2023-07-17 23:xx和2023-07-18 00:xx),当前逻辑仍按小时归并(23-24与0-1分属不同组),符合“每小时区间”本意;如需按日期+小时双重分组(即区分每日的10-11),请改用GROUP BY DATE(date_time), HOUR(date_time)并调整hour_range为CONCAT(DATE(date_time), ' ', HOUR(...), '-', HOUR(...) + 1); - 时间字段类型应为
DATETIME或TIMESTAMP,若为字符串需先用STR_TO_DATE()转换,否则HOUR()返回NULL; - 结果为标准二维结果集(
hour_range,count),应用层可轻松构建Map<string integer></string>(如 Java 中rs.getString("hour_range") → rs.getInt("count"))。
该方案简洁高效,无需复杂窗口函数或子查询,单次扫描即可完成统计,适用于百万级数据场景。结合索引优化(如对 date_time 建立 B-tree 索引),性能表现优异。










