如何用下一行中的值替换空值

Pat*_*zyk 22 sql sql-server

我的SQL查询代码中需要支持。我必须用下一行的非空值替换一列中的空值。

作为示例,我们可以使用以下代码:

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
Run Code Online (Sandbox Code Playgroud)

当我使用Lead函数时,会得到此值,但不适用于NULL。我需要得到的是:

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
Run Code Online (Sandbox Code Playgroud)

卜从我的查询:

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#
Run Code Online (Sandbox Code Playgroud)

我有:在此处输入图片说明

Zho*_*rov 15

下一种方法可能会有所帮助。您需要其他APPLY运算符来查找没有NULL值的第一条记录:

T-SQL:

SELECT 
    v1.[r#], 
    CASE 
        WHEN v1.[value] IS NULL THEN v2.[value]
        ELSE v1.[value]
    END AS [value]
 FROM @value v1
 OUTER APPLY (
    SELECT TOP 1 [Value]
    FROM @value 
    WHERE (v1.[r#] < [r#]) AND [value] IS NOT NULL
) v2
Run Code Online (Sandbox Code Playgroud)

输出:

r#  value
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
Run Code Online (Sandbox Code Playgroud)

  • 该 CASE 语句看起来更简洁,如`COALESCE(v1.[value], v2.[value]) AS [value]` (2认同)

Gor*_*off 5

您可以使用窗口功能执行此操作。不幸的是,SQL Server不支持上的IGNORE NULLs选项LEAD(),因此这不是一个选项。

但是,可以使用两个级别的窗口功能:

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#;
Run Code Online (Sandbox Code Playgroud)

在13行上,性能差异可能并不明显。但是,随着行数的增加,这应该具有更好的性能。