SQL 服务器在组中填补月份空白
SQL Server Fill Month Gaps in Groups
我有一个 table 例如如下:
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)
我希望用 0.00 值(在 Avalue 列中)填补月份(在上面的 CheckMonth 列中)的空白。
数据按 Aid 和 Bid 列分组。
结果应如下所示:
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
感谢任何帮助。
谢谢
一个选项使用递归查询为每个 (aid, bid)
元组生成月份开始;然后,您可以 left join
使用原始 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
我有一个 table 例如如下:
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)
我希望用 0.00 值(在 Avalue 列中)填补月份(在上面的 CheckMonth 列中)的空白。 数据按 Aid 和 Bid 列分组。
结果应如下所示:
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
感谢任何帮助。 谢谢
一个选项使用递归查询为每个 (aid, bid)
元组生成月份开始;然后,您可以 left join
使用原始 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