• romina - Monday, June 25, 2018 8:28 AM

    Thank you HanShi
    Looking into your solution too.

    You guys have no idea how much I appreciate you taking the time to help me out with this. It's been so frustrating ... it looks simple and yet it hasn't been!

    Thanks

    A solution using analytical function max() over(order by). This looks at all the available dates for an institution and generates 12 rows one for each month. I have slightly modified the input DML statements to test various scenarios. More complicated than the earlier solutions i guess but made more generic


    CREATE TABLE data
    (
      ReportingMonth datetime,
      Institution varchar(4),
      Totals integer
    );
    GO

    INSERT INTO data
    VALUES
    ('2018-01-01','Ins1',32),
    ('2018-02-01','Ins1',37),
    ('2018-03-01','Ins1',32),
    ('2018-04-01','Ins1',40),
    ('2018-05-01','Ins1',38),
    ('2018-06-01','Ins1',37),
    ('2018-09-01','Ins1',40),
    ('2019-09-01','Ins1',42),
    ('2018-01-01','Ins2',145),
    ('2018-02-01','Ins2',155),
    ('2018-01-01','Ins3',1489),
    ('2018-02-01','Ins3',1487),
    ('2018-03-01','Ins3',1485);
    GO

    with generate_12_months
    as (
       select dateadd(month
                      ,y.rnk-1
                      ,cast(concat(year_val,'-','01','-','01') as date)
                     ) as running_months
              ,x.institution 
          from (select top 12
                       row_number() over(order by (select null)) as rnk
                  from sys.objects
                )y
           join (select distinct /* for each distinct year in a institution generates 12 months*/
                        datepart(year,reportingmonth) as year_val
                        ,Institution
                    from data
                 )x
               on 1=1
        )
    ,interim_data
     as (
         select cd.running_months
                ,cd.institution
                ,d.totals
                ,d.reportingmonth        
            from generate_12_months cd
       left join data d
              on cd.running_months=d.reportingmonth
             and cd.institution=d.institution
          )
    ,interim_data2
      as(/*the max reportingmonth gets the first not null value of the month ordered by running_months*/
         select *
                ,max(x.reportingmonth) over(partition by x.institution order by x.running_months) as max_val
           from interim_data x
          )
    select *
           ,max(y.totals) over(partition by y.institution,y.max_val) as not_null_totals
      from interim_data2 y