按年和月填充SQL行

时间:2018-06-18 08:52:27

标签: sql sql-server

我有以下数据表

  CREATE TABLE #Temp(AccountId NVARCHAR(100),Churn NVARCHAR(100), [Month] INT, [Yr] INT)
    Insert Into #Temp Values('Tst05716825','Active',9,2016)
    Insert Into #Temp Values('Tst05716825','Active',12,2016);
    Insert Into #Temp Values('Tst05716825','Suspend',3,2017);
    Insert Into #Temp Values('Tst05716825','Suspend',8,2017);
   Insert Into #Temp Values('Tst05716825','Terminate',10,2017);
    SELECT * FROM #Temp

输出如下

AccountId   Churn    Month  Yr
Tst05716825 Active   9    2016
Tst05716825 Active   12   2016
Tst05716825 Suspend   3   2017
Tst05716825 Suspend   8   2017
Tst05716825 Terminate 10  2017

但是我需要按照之前的价值填写缺少的年份和月份。需要输出如下:

AccountId   Churn   Month   Yr
Tst05716825 Active  9   2016
Tst05716825 Active  10  2016
Tst05716825 Active  11  2016
Tst05716825 Active  12  2016
Tst05716825 Active  1   2017
Tst05716825 Active  2   2017
Tst05716825 Suspend 3   2017
Tst05716825 Suspend 4   2017
Tst05716825 Suspend 5   2017
Tst05716825 Suspend 6   2017
Tst05716825 Suspend 7   2017
Tst05716825 Suspend 8   2017
Tst05716825 Suspend 9   2017
Tst05716825 Terminate 10  2017

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

尝试这种方法:

--first you declare variables to hold minimum date and maximum date
declare @start date, @end date;
select @start = MIN(dt), @end = MAX(dt) from (
    SELECT DATEFROMPARTS(Yr, [Month], 1) dt FROM #Temp
) a;

--this cte will define complete set of months within range given in table (based on variables)
with cte as (
    select @start dt
    union all
    select DATEADD(month, 1, dt) from cte
    where dt < @end
)

--here you will use cte to left join data from your table,
--then, based on non-null values from your table you'll create grouping column
--that will allow us to specify values for periods of time, when there was no data in your table
select [month], yr,
       MAX(accountid) over (partition by groupingCol) accountid,
       MAX(churn) over (partition by groupingCol) churn
from (
    select c.[month], c.[yr], accountid, churn,
           sum(case when accountid is null then 0 else 1 end) over (partition by (select null) order by c.yr, c.[month]) [groupingCol]
    from (
        select DATEPART(month, dt) [month], DATEPART(YEAR, dt) yr from cte
    ) [c] left join #Temp [t] on [c].[month] = t.[month] and c.[yr] = t.[yr]
) a