sqlsql-server

How to replace null value with value from the next row


I need support in my sql query code. I have to replace null value in a column with not-null value from the next row.

as a example we can use this code:

declare   @value table (r# int, value varchar(15))
insert into @value ( r#, value ) values
 (1, NULL   ) ,
 (2, 'January'), 
 (3, 'February' ), 
 (4, NULL    ),
 (5, 'March'  ),
 (6, NULL    ),
(7, Null  ),
(8, 'December' ),
(9, Null ),
(10, Null  ),
(11, Null  ),
(12, 'November' ),
(13, Null )
select * from @value

When I use lead function I get this value but it does not work with NULLs. What I need is to get:

1 January
2 January
3 February
4 March
5 March
6 December
7 December
8 December
9 November
10 November
11 November
12 November
13 NULL

Bu from my query :

SELECT r#, 
  value
 ,case when value is null  then Lead(value) OVER ( order by  r#  asc) else value end as RESULT 
FROM @value
order by r#

I have:enter image description here


Solution

  • You can do this with window functions. Unfortunately, SQL Server doesn't support the IGNORE NULLs option on LEAD(), so that is not an option.

    However, you can use two levels of window functions:

    select v.r#, v.value,
           coalesce(v.value, max(value) over (partition by next_r#)) as imputed_value
    from (select v.*,
                 min(case when value is not null then r# end) over (order by r# desc) as next_r#
          from @value v
         ) v
    order by v.r#;
    

    On 13 rows, the performance difference is probably not noticeable. However, this should have much better performance as the number of rows increases.