如何从年月分列存储的表中查询近6个月数据并按ID分组取TOP5
SQL实现分栏存储年月的近6个月TOP5统计
核心实现思路
要解决年月分栏存储的时间范围筛选问题,避免跨年场景下的逻辑错误,整体执行逻辑如下:
- 将年、月字段转换为可直接比较的数值(总月数),规避跨年对比错误
- 计算当前日期往前推6个月的临界总月数,过滤符合时间范围的记录
- 对过滤后的记录按指定ID分组统计量级,倒序排序后取前5条结果
通用SQL实现(兼容绝大多数数据库)
SELECT some_id, COUNT(table_id) AS number FROM mytable -- 总月数对比逻辑:记录年月总月数 >= 当前时间往前推6个月的总月数 WHERE mt_year * 12 + mt_month >= YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 5 GROUP BY some_id ORDER BY number DESC LIMIT 5;
注:临界计算中减5代表包含当前月共统计6个月数据,如需统计当前月之前的6个完整自然月,可调整为减6
适配示例测试数据的SQL
针对提供的测试数据(最新数据年月为2021年12月),可使用固定临界值验证效果:
SELECT some_id, COUNT(table_id) AS number FROM mytable WHERE mt_year * 12 + mt_month >= 2021 * 12 + 12 - 5 GROUP BY some_id ORDER BY number DESC LIMIT 5;
可选的日期函数实现(支持STR_TO_DATE的数据库可用)
如果你的数据库支持字符串转日期函数,也可以用更直观的日期对比写法:
SELECT some_id, COUNT(table_id) AS number FROM mytable WHERE STR_TO_DATE(CONCAT(mt_year, '-', mt_month, '-01'), '%Y-%m-%d') >= DATE_SUB(CURRENT_DATE, INTERVAL 6 MONTH) GROUP BY some_id ORDER BY number DESC LIMIT 5;
注意事项
不要直接使用mt_year = xxx AND mt_month >= xxx的筛选逻辑,会过滤掉上一年度末符合时间范围的记录,无法处理跨年的近6个月统计需求。
内容的提问来源于stack exchange,提问作者Rodrick
相关产品推荐
相关产品推荐

