SQL Server存储过程查询日汇总无数据日期如何显示Total为0?
实现补全空日期汇总的解决方案
方法1:使用你摸索的UNION ALL方案(改动最小)
你自己想到的在循环插入语句中加UNION ALL补0行的方法是完全可行的,修改后的完整插入逻辑如下:
while @fd <= @To_day begin insert into @dt Select Day_get = Convert(nvarchar(10), @fd, 20), Total = sum(isnull(Total,0)) from hipos_BH_Info where Convert(nvarchar(10), Day_get, 20) = @fd and Cancel_Huy = 0 group by Day_get, Total UNION ALL Select Day_get = Convert(nvarchar(10), @fd, 20), Total = 0 set @fd = @fd + 1 --Add 1 day end
逻辑原理:当天没有业务数据时,原业务查询会返回空结果,追加的UNION ALL行可以保证每天至少有一条Total为0的记录插入临时表。后续分组求和时,有业务数据的日期会把实际值和0相加,结果不受影响;无业务数据的日期就会直接返回0,刚好符合你的需求。
方法2:递归CTE生成连续日期(性能更优,无需循环)
如果日期查询范围较大,循环逐天插入的效率偏低,可以用递归CTE直接生成完整日期序列,再左关联业务表实现需求,完整存储过程代码如下:
CREATE PROCEDURE [dbo].[hipos_BC_BH_TEST] @From_day datetime, @To_day datetime AS BEGIN -- 生成@From_day到@To_day的所有连续日期 ;WITH AllDays AS ( SELECT @From_day AS Day_date UNION ALL SELECT DATEADD(DAY, 1, Day_date) FROM AllDays WHERE Day_date < @To_day ) SELECT Day_get = CONVERT(nvarchar(10), a.Day_date, 20), Total = ISNULL(SUM(b.Total), 0) FROM AllDays a LEFT JOIN hipos_BH_Info b ON CONVERT(nvarchar(10), b.Day_get, 20) = CONVERT(nvarchar(10), a.Day_date, 20) AND b.Cancel_Huy = 0 GROUP BY CONVERT(nvarchar(10), a.Day_date, 20) OPTION (MAXRECURSION 0) -- 解除递归层数限制,支持超过100天的查询范围 END
这个方案省去了临时表和循环操作,逻辑更简洁,查询效率更高。
内容的提问来源于stack exchange,提问作者nguyenhuy289
相关产品推荐
相关产品推荐

