我的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
当我使用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
我的查询中的Bu:
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#
答案 0 :(得分:14)
下一种方法可能会有所帮助。您需要其他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
输出:
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
答案 1 :(得分:4)
您可以使用窗口功能执行此操作。不幸的是,SQL Server不支持IGNORE NULL
上的LEAD()
s选项,因此这不是一个选项。
但是,您可以使用两个级别的窗口功能:
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#;
在13行上,性能差异可能并不明显。但是,随着行数的增加,这应该具有更好的性能。
答案 2 :(得分:2)
您可以使用相关子查询尝试以下sql代码
SELECT v1.r#,CASE WHEN value IS NOT NULL THEN v1.Value
ELSE ( SELECT TOP 1 value
FROM @value v2
WHERE v2.r# > v1.r# AND v2.[value] IS NOT NULL
) END Value
FROM @value v1
结果
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
答案 3 :(得分:1)
以下查询在SQL Server中有效:
;WITH CTE_Value
AS (
SELECT R#, Value
FROM @value AS T
WHERE Value IS NOT NULL
UNION ALL
SELECT t.r#, c.Value
FROM @value AS t
INNER JOIN CTE_Value AS c ON t.r# + 1 = c.r#
WHERE t.Value IS NULL
)
SELECT *
FROM CTE_Value
UNION ALL
SELECT v.*
FROM @value AS v
LEFT JOIN CTE_value AS c ON v.r# = c.r#
WHERE c.r# IS NULL
ORDER BY r#