在看到许多示例之后,我没有找到一种简单的方法来用最后一个值替换每列的NULL值。
旋转表之后,我有以下示例:
IDS 1234,4567,7890
| 1234 | 4567 | 7890 |
| 1 | 2 | 3 |
| NULL | 4 | 5 |
| NULL | 6 | NULL |
| 8 | NULL | 9 |
结果:
| 1234 | 4567 | 7890 |
| 1 | 2 | 3 |
| 1 | 4 | 5 |
| 1 | 6 | 5 |
| 8 | 6 | 9 |
答案 0 :(得分:1)
我们不知道您的DBMS,但是对于大多数DBMS,lag()
窗口分析函数用于以前的记录,而coalesce()
函数用于替代空值。因此,尝试使用:
with t1( id, col_1234, col_4567, col_7890 ) as
(
select 1, 1 , 2 , 3 union all
select 2, NULL, 4 , 5 union all
select 3, NULL, 6 , NULL union all
select 4, 8 ,NULL, 9
), t2 as
(
select id,
coalesce( col_1234, lag(col_1234) over (order by id) ) as col_1234,
coalesce( col_4567, lag(col_4567) over (order by id) ) as col_4567,
coalesce( col_7890, lag(col_7890) over (order by id) ) as col_7890
from t1
)
select coalesce( col_1234, lag(col_1234) over (order by id) ) as col_1234,
col_4567, col_7890
from t2
答案 1 :(得分:1)
使用CURSOR是因为结果集中有超过2个连续的NULL的可能性,并且LEAD和LAG方法将无法工作,因为它们只能检查1行。
DECLARE @id INT,@col_1234 INT, @col_4567 INT,@col_7890 INT
DECLARE @id_prev INT,@col_1234_prev INT,@col_4567_prev INT,@col_7890_prev INT
DECLARE @LoopOne INT = 1
DECLARE @TempTable TABLE
(
id INT, col_1234 INT, col_4567 INT, col_7890 INT
)
DECLARE db_cursor CURSOR FOR
SELECT id, col_1234, col_4567, col_7890
FROM your_table
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @id, @col_1234, @col_4567, @col_7890
WHILE @@FETCH_STATUS = 0
BEGIN
IF @LoopOne = 1
BEGIN
SET @id_prev = @id
SET @col_1234_prev = @col_1234
SET @col_4567_prev = @col_4567
SET @col_7890_prev = @col_7890
INSERT INTO @TempTable(id, col_1234, col_4567, col_7890)
VALUES (@id, @col_1234, @col_4567, @col_7890 )
SET @LoopOne = 2
END
ELSE
BEGIN
SET @id_prev = CASE WHEN @id IS NULL THEN @id_prev ELSE @id END
SET @col_1234_prev = CASE WHEN @col_1234 IS NULL THEN @col_1234_prev ELSE @col_1234 END
SET @col_4567_prev = CASE WHEN @col_4567 IS NULL THEN @col_4567_prev ELSE @col_4567 END
SET @col_7890_prev = CASE WHEN @col_7890 IS NULL THEN @col_7890_prev ELSE @col_7890 END
INSERT INTO @TempTable(id, col_1234, col_4567, col_7890)
VALUES (@id_prev, @col_1234_prev, @col_4567_prev, @col_7890_prev )
END
FETCH NEXT FROM db_cursor INTO @id, @col_1234, @col_4567, @col_7890
END
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT * FROM @TempTable