SQL Server按天统计活动并补全缺失日期(计数为0)的查询求助
解决SQL Server按天统计并补全无记录日期的问题
嘿,作为SQL新手能想到按天分组统计已经超棒啦!要搞定无记录日期补0的需求,核心思路是先生成连续的目标日期范围,再和你的业务表做左连接统计。我给你写了直接能运行的示例,适配SQL Server环境,一步步来:
核心思路
你的原表只有有数据的日期,所以必须先造出包含所有需要日期的“日期序列表”,再用左连接把业务表的数据关联上去——左连接会保留日期序列里的所有日期,哪怕业务表没有对应记录,最后用COUNT(业务表字段)就能把无记录的日期计数设为0。
可运行完整代码(动态取原表的日期范围)
这个版本会自动从你的表中取最早和最晚的日期,生成中间的所有连续日期,不用手动写死日期:
-- 1. 用递归CTE生成连续日期范围 WITH DateRange AS ( -- 起始日期:取表中最早的记录日期 SELECT CAST(MIN(Created) AS DATE) AS DateDay FROM YourTableName -- 👉 这里替换成你的实际表名! UNION ALL -- 递归生成下一天的日期,直到表中最晚的记录日期 SELECT DATEADD(DAY, 1, DateDay) FROM DateRange CROSS JOIN (SELECT MAX(Created) AS MaxDate FROM YourTableName) AS MaxDateSub WHERE DateDay < CAST(MaxDateSub.MaxDate AS DATE) ) -- 2. 左连接原表,按日期统计活动数量 SELECT dr.DateDay, COUNT(yt.Created) AS ActivityCount -- 用原表字段计数,无匹配时自动为0 FROM DateRange dr LEFT JOIN YourTableName yt ON CAST(yt.Created AS DATE) = dr.DateDay GROUP BY dr.DateDay ORDER BY dr.DateDay;
固定日期范围的版本(如果不想动态取)
如果你已经明确知道要统计的日期范围(比如从2017-10-03到2017-10-10),可以用这个更简单的写法:
-- 1. 生成固定的连续日期范围 WITH DateRange AS ( SELECT CAST('2017-10-03' AS DATE) AS DateDay UNION ALL SELECT DATEADD(DAY, 1, DateDay) FROM DateRange WHERE DateDay < CAST('2017-10-10' AS DATE) ) -- 2. 左连接统计 SELECT dr.DateDay, COUNT(yt.Created) AS ActivityCount FROM DateRange dr LEFT JOIN YourTableName yt ON CAST(yt.Created AS DATE) = dr.DateDay GROUP BY dr.DateDay ORDER BY dr.DateDay;
关键注意点(敲黑板!)
- 一定要把代码里的
YourTableName替换成你实际的表名! - 用
COUNT(yt.Created)而不是COUNT(*):左连接无匹配时yt.Created是NULL,COUNT会忽略NULL值,所以得到0;如果用COUNT(*)会把NULL行也算成1,结果就错啦。 - SQL Server的递归CTE默认递归次数是100,如果你的日期范围超过100天,需要在结尾加
OPTION (MAXRECURSION 0)来取消限制。
运行上面的代码,就能得到你想要的结果:
'2017-10-03', 1
'2017-10-04', 0
'2017-10-05', 0
'2017-10-06', 0
'2017-10-07', 3
'2017-10-08', 7
'2017-10-09', 0
'2017-10-10', 1
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

