Sql-server – Last Non-NULL Value

sql serversql-server-2012

In the below table I am attempting to fill in NULL values with the last known non-null value if the current value is null. If the first value is NULL it should remain NULL:

EntryDate   CustId  Stat    Desk    BkGrp   CyGrp   NextDate    Amt
5/9/2018    19001   PLX     H6      NULL    NULL    NULL        NULL
5/31/2018   19001   NULL    NULL    0       13      6/17/2018   1063.51
6/4/2018    19001   NULL    B98     0       13      6/17/2018   1013.51
6/21/2018   19001   PLY     NULL    NULL    NULL    7/17/2018   1033.15
7/18/2018   19001   NULL    NULL    0       13      7/17/2018   1058.15
7/22/2018   19001   NULL    NULL    1       13      8/17/2018   1077.91
1/29/2016   19503   PLZ     H6      NULL    NULL    NULL        NULL
5/31/2018   19503   NULL    NULL    1       5       6/6/2018    541.11
6/7/2018    19503   NULL    NULL    1       NULL    6/6/2018    576.11
6/10/2018   19503   PLA     NULL    2       5       7/6/2018    589.3
7/8/2018    19503   PLA     NULL    NULL    5       7/6/2018    624.3
7/11/2018   19503   NULL    NULL    3       NULL    8/6/2018    639.84

I am trying to create this:

EntryDate   CustId  Stat    Desk    BkGrp   CyGrp   NextDate    Amt
5/9/2018    19001   PLX     H6      NULL    NULL    NULL        NULL
5/31/2018   19001   PLX     H6      0       13      6/17/2018   1063.51
6/4/2018    19001   PLX     B98     0       13      6/17/2018   1013.51
6/21/2018   19001   PLY     B98     0       13      7/17/2018   1033.15
7/18/2018   19001   PLY     B98     0       13      7/17/2018   1058.15
7/22/2018   19001   PLY     B98     1       13      8/17/2018   1077.91
1/29/2016   19503   PLZ     H6      NULL    NULL    NULL        NULL
5/31/2018   19503   PLZ     H6      1       5       6/6/2018    541.11
6/7/2018    19503   PLZ     H6      1       5       6/6/2018    576.11
6/10/2018   19503   PLA     H6      2       5       7/6/2018    589.3
7/8/2018    19503   PLA     H6      2       5       7/6/2018    624.3
7/11/2018   19503   PLA     H6      3       5       8/6/2018    639.84

I have looked up various methods including The Last non NULL Puzzle but can't get anything to work across 6 columns with changing data.

This is on SQL Server 2012.

Best Answer

You can use subqueries to get the latest not null value like:

SELECT t1.entrydate,
       t1.custid,
       (SELECT TOP 1
               t2.stat
               FROM elbat t2
               WHERE t2.custid = t1.custid
                     AND t2.entrydate <= t1.entrydate
                     AND t2.stat IS NOT NULL
               ORDER BY t2.entrydate DESC) stat,
       ...
       (SELECT TOP 1
               t2.amt
               FROM elbat t2
               WHERE t2.custid = t1.custid
                     AND t2.entrydate <= t1.entrydate
                     AND t2.amt IS NOT NULL
               ORDER BY t2.entrydate DESC) amt
       FROM elbat t1
       ORDER BY t1.custid,
                t1.entrydate;

If (custid, entrydate) isn't unique -- i.e. there are more possible latest values -- you might want to find an other second criteria to ORDER BY. Like it stands it'd randomly get any of the latest (not null) values in such a case.