Reputation: 439
I have a set of data from a table that would only be populated if a user has data for a certain month just like this:
Month | MonthName | Value
3 | March | 136.00
4 | April | 306.00
7 | July | 476.00
12 | December | 510.48
But what I need is to check if a month is skipped then adding the value the month before so the end result would be like this:
Month | MonthName | Value
3 | March | 136.00
4 | April | 306.00
5 | May | 306.00 -- added data
6 | June | 306.00 -- added data
7 | July | 476.00
8 | August | 476.00 -- added data
9 | September | 476.00 -- added data
10 | October | 476.00 -- added data
11 | November | 476.00 -- added data
12 | December | 510.48
How can I do this dynamically on SQL Server?
Upvotes: 1
Views: 213
Reputation: 3811
you can use spt_values to get continuous number 1-12, and then left join your table by max(month)
select t1.month
,datename(month,datefromparts(2020, t1.month, 1)) monthname
,t2.value
from (
select top 12 number + 1 as month from master..spt_values
where type = 'p'
) t1
left join t t2 on t2.month = (select max(month) from t tmp where tmp.month < = t1.month)
where t2.month is not null
CREATE TABLE T
([Month] int, [MonthName] varchar(8), [Value] numeric)
;
INSERT INTO T
([Month], [MonthName], [Value])
VALUES
(3, 'March', 136.00),
(4, 'April', 306.00),
(7, 'July', 476.00),
(12, 'December', 510.48)
;
Demo Link SQL Server 2012 | db<>fiddle
if you have year column then you need to fix the script.
Upvotes: 1
Reputation: 1269703
One method is a recursive CTE:
with cte as (
select month, value, lead(month) over (order by month) as next_month
from t
union all
select month + 1, value, next_month
from cte
where month + 1 < next_month
)
select month, datename(month, datefromparts(2020, month, 1)) as monthname, value
from cte
order by month;
Here is a db<>fiddle.
Upvotes: 3