SQL查询近14天每日数据:BETWEEN范围无匹配时默认返回0方案
实现方案
核心思路
问题的根因是业务表中没有无新增日期的对应记录,聚合后自然不会返回这些日期。解决方法是先构造包含近14天所有日期的临时序列,再和业务表的统计结果做左关联,缺失的统计值默认补0即可。
MySQL环境实现代码(支持MySQL8.0及以上版本)
WITH RECURSIVE date_series AS ( -- 递归生成近14天的连续日期序列 SELECT CURDATE() AS day UNION ALL SELECT SUBDATE(day, 1) FROM date_series WHERE day > SUBDATE(CURDATE(), 13) ) SELECT ds.day, IFNULL(COUNT(b.id), 0) AS count FROM date_series ds LEFT JOIN businesses b ON ds.day = b.created_at GROUP BY ds.day ORDER BY ds.day DESC;
代码说明
- 递归CTE
date_series负责生成连续的14天日期,覆盖从当前日期到13天前的全部时间范围 - 用左连接关联业务表
businesses,保证所有日期都能保留在结果中 IFNULL(COUNT(b.id), 0)处理无数据的日期,自动将空统计值置为0- 最终按日期倒序排列,和你给出的期望输出顺序完全一致
注意:如果你的
created_at字段是带时分秒的datetime类型,需要将关联条件修改为ON ds.day = DATE(b.created_at),避免日期匹配失败。
低版本MySQL兼容方案(不支持CTE的场景)
如果你的MySQL版本低于8.0不支持递归CTE,可以用数字辅助表的方式生成日期序列:
SELECT ds.day, IFNULL(COUNT(b.id), 0) AS count FROM ( SELECT SUBDATE(CURDATE(), num) AS day FROM ( SELECT 0 num UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 ) nums ) ds LEFT JOIN businesses b ON ds.day = b.created_at GROUP BY ds.day ORDER BY ds.day DESC;
内容的提问来源于stack exchange,提问作者emmaakachukwu
相关产品推荐
相关产品推荐

