Reputation: 71
I have a table for example like below:
declare @test table(Aid int, Bid int, CheckMonth date, Avalue decimal(18,2))
insert into @test (Aid, Bid, CheckMonth, Avalue)
values (1, 4, '2014-07-05', 123.00)
,(1, 4, '2014-08-01', 467.00)
,(1, 4, '2014-11-03', 876.00)
,(1, 4, '2014-12-01', 876.00)
,(2, 6, '2016-01-02', 23.00)
,(2, 6, '2016-03-14', 56.00)
,(2, 6, '2016-04-17', 98.00)
,(2, 6, '2016-07-01', 90.00)
I wish to fill the gaps in months (in CheckMonth column above) with 0.00 values (in Avalue column). Data is grouped by Aid and Bid columns.
The result should look like below:
Aid Bid CheckMonth Avalue
1 4 '2014-07-05' 123.00
1 4 '2014-08-01' 467.00
1 4 '2014-09-01' 0.00 -->inserted
1 4 '2014-10-01' 0.00 -->inserted
1 4 '2014-11-03' 876.00
1 4 '2014-12-01' 876.00
2 6 '2016-01-02' 23.00
2 6 '2016-02-01' 0.00 -->inserted
2 6 '2016-03-14' 56.00
2 6 '2016-04-17' 98.00
2 6 '2016-05-01' 0.00 -->inserted
2 6 '2016-06-01' 0.00 -->inserted
2 6 '2016-07-01' 90.00
Any help is appreciated. Thanks.
Upvotes: 0
Views: 233
Reputation: 222462
One option uses a recursive query to generate the month starts for each (aid, bid)
tuple; you can then left join
the generated resultset with the original table:
with cte as (
select
aid,
bid,
datefromparts(year(min(checkMonth)), month(min(checkMonth)), 1) dt,
datefromparts(year(max(checkMonth)), month(max(checkMonth)), 1) maxDt
from @test
group by aid, bid
union all
select
aid,
bid,
dateadd(month, 1, dt),
maxDt
from cte
where dt < maxDt
)
select c.aid, c.bid, coalesce(t.checkMonth, c.dt) checkMonth, coalesce(t.avalue, 0) avalue
from cte c
left join @test t
on t.aid = c.aid
and t.bid = c.bid
and t.checkMonth >= c.dt
and t.checkMonth < dateadd(month, 1, c.dt)
order by c.aid, c.bid, c.dt
aid | bid | checkMonth | avalue --: | --: | :--------- | :----- 1 | 4 | 2014-07-05 | 123.00 1 | 4 | 2014-08-01 | 467.00 1 | 4 | 2014-09-01 | 0.00 1 | 4 | 2014-10-01 | 0.00 1 | 4 | 2014-11-03 | 876.00 1 | 4 | 2014-12-01 | 876.00 2 | 6 | 2016-01-02 | 23.00 2 | 6 | 2016-02-01 | 0.00 2 | 6 | 2016-03-14 | 56.00 2 | 6 | 2016-04-17 | 98.00 2 | 6 | 2016-05-01 | 0.00 2 | 6 | 2016-06-01 | 0.00 2 | 6 | 2016-07-01 | 90.00
Upvotes: 1