我需要填写数据中缺少的时间间隔,并为任何间隙填充Cnt列为0。我是否需要使用日历表?
我的查询结果已经汇总,我只需要添加空白。
select name
,YR
,MO
,[Cnt]
from dbo.OON
当前输出:
Name | YR | MO | Cnt
Kelly | 2014 | 1 | 197
Kelly | 2014 | 3 | 200
Kelly | 2014 | 5 | 300
Kelly | 2015 | 2 | 100
Kelly | 2015 | 3 | 50
Kelly | 2015 | 6 | 70
期望的输出:
Name | YR | MO | Cnt
Kelly | 2014 | 1 | 197
Kelly | 2014 | 2 | 0
Kelly | 2014 | 3 | 200
Kelly | 2014 | 4 | 0
Kelly | 2014 | 5 | 300
Kelly | 2014 | 6 | 0
Kelly | 2014 | 7 | 0
Kelly | 2014 | 8 | 0
Kelly | 2014 | 9 | 0
Kelly | 2014 | 10 | 0
Kelly | 2014 | 11 | 0
Kelly | 2014 | 12 | 0
Kelly | 2015 | 1 | 0
Kelly | 2015 | 2 | 100
Kelly | 2015 | 3 | 50
Kelly | 2015 | 4 | 0
Kelly | 2015 | 5 | 0
Kelly | 2015 | 6 | 70
Kelly | 2015 | 7 | 0
Kelly | 2015 | 8 | 0
Kelly | 2015 | 9 | 0
Kelly | 2015 | 10 | 0
Kelly | 2015 | 11 | 0
Kelly | 2015 | 12 | 0
答案 0 :(得分:2)
另一个选项是ad-hoc计数表
Declare @OON table (Name varchar(25),YR int,MO int,Cnt int)
Insert Into @OON values
('Kelly' , 2014 , 1 , 197),
('Kelly' , 2014 , 3 , 200),
('Kelly' , 2014 , 5 , 300),
('Kelly' , 2015 , 2 , 100),
('Kelly' , 2015 , 3 , 50),
('Kelly' , 2015 , 6 , 70)
Declare @PerBeg date = '2014-01-01'
Declare @Months int = 24
Select B.Name
,Yr=Year(A.D)
,MO=Month(A.D)
,Cnt=IsNull(C.Cnt,0)
From (Select Top (@Months) D=DateAdd(MM,-1+Row_Number() Over (Order By (Select null)),@PerBeg) From master..spt_values) A
Cross Join (Select Distinct Name from @OON) B
Left Join @OON C on B.Name=C.Name and Year(A.D)=C.Yr and Month(A.D)=C.MO
返回
Name Yr MO Cnt
Kelly 2014 1 197
Kelly 2014 2 0
Kelly 2014 3 200
Kelly 2014 4 0
Kelly 2014 5 300
Kelly 2014 6 0
Kelly 2014 7 0
Kelly 2014 8 0
Kelly 2014 9 0
Kelly 2014 10 0
Kelly 2014 11 0
Kelly 2014 12 0
Kelly 2015 1 0
Kelly 2015 2 100
Kelly 2015 3 50
Kelly 2015 4 0
Kelly 2015 5 0
Kelly 2015 6 70
Kelly 2015 7 0
Kelly 2015 8 0
Kelly 2015 9 0
Kelly 2015 10 0
Kelly 2015 11 0
Kelly 2015 12 0
答案 1 :(得分:0)
你可以有一个永久的日历表,或者你可以使用普通的Numbers表逃脱。无论哪种方式,建立递归cte是更优选的解决方案。但是,如果它是一次性报告,您可以轻松地使用简单的CTE,如下所示:
;with n as (
select 1 as n
UNION ALL
SELECT n + 1 FROM n WHERE n < 20),
years as (
select 2013 + n.n as [year] from n where n < 3),
months as (
select 0 + n.n as [month] from n where n < 13)
select r.name, years.[year], months.[month], coalesce(r.Cnt,0)
from years cross join months
left join dbo.OON r on years.[year] = r.[YR] and months.[month] = r.[MO]
order by 1,2,3
在上面的查询中,您可能希望使用years
cte的初始值和年份数作为参数