用以前的 NOT NULL 行更新 NULL 行
Update the NULL Rows with Previous NOT NULL Rows
我有一个场景,我的 table 有 2 列,一列有一系列日期,另一列有一些值。现在我需要使用与最近日期对应的值更新空值,如下所示。
我无法使用 LEAD 和 LAG 函数,因为我正在使用 SQL Server 2008R2。
示例数据如下。
DECLARE @Table TABLE
(
Date_D DATE,
Val INT
);
INSERT INTO @Table
(
Date_D,
Val
)
VALUES
('2019-06-15', 2),
('2019-06-16', NULL),
('2019-06-17', NULL),
('2019-06-18', 7),
('2019-06-19', 1),
('2019-06-20', 5),
('2019-06-21', NULL),
('2019-06-22', NULL),
('2019-06-23', NULL),
('2019-06-24', NULL),
('2019-06-25', 9),
('2019-06-26', 5),
('2019-06-27', 3),
('2019-06-28', 4),
('2019-06-29', NULL),
('2019-06-30', 1)
SELECT * FROM @Table
一种方法是使用 sub-select,选择当前 Date_D
.
之前的 TOP 1 non-NULL 值
你可以这样做
SELECT Date_D, CASE WHEN Val IS NULL THEN
(
SELECT TOP 1 Val
FROM @Table
WHERE Val IS NOT NULL AND Date_D < T.Date_D
ORDER BY Date_D DESC
) ELSE Val END
FROM @Table T;
如果您想更新 table 然后将其与结果结合起来。
对于UPDATE
;WITH CTE AS
(
SELECT Date_D, CASE WHEN Val IS NULL THEN
(
SELECT TOP 1 Val
FROM @Table
WHERE Val IS NOT NULL AND Date_D < T.Date_D
ORDER BY Date_D DESC
) ELSE Val END Val
FROM @Table T
)
UPDATE T
SET T.Val = CTE.Val
FROM @Table T INNER JOIN CTE
ON T.Date_D = CTE.Date_D
WHERE T.Val IS NULL; --You can also AND Date_D BETWEEN StartDate AND EndDate
看看它在 live demo
上是如何工作的
使用相关子查询更新:
UPDATE T0
SET Val = (
SELECT TOP 1 Val
FROM @Table As T1
WHERE Val IS NOT NULL
AND T0.Date_D > T1.Date_D
ORDER BY Date_D DESC
)
FROM @Table As T0
WHERE Val IS NULL
验证:
SELECT *
FROM @Table
结果:
Date_D Val
15.06.2019 2
16.06.2019 2
17.06.2019 2
18.06.2019 7
19.06.2019 1
20.06.2019 5
21.06.2019 5
22.06.2019 5
23.06.2019 5
24.06.2019 5
25.06.2019 9
26.06.2019 5
27.06.2019 3
28.06.2019 4
29.06.2019 4
30.06.2019 1
我有一个场景,我的 table 有 2 列,一列有一系列日期,另一列有一些值。现在我需要使用与最近日期对应的值更新空值,如下所示。
我无法使用 LEAD 和 LAG 函数,因为我正在使用 SQL Server 2008R2。
示例数据如下。
DECLARE @Table TABLE
(
Date_D DATE,
Val INT
);
INSERT INTO @Table
(
Date_D,
Val
)
VALUES
('2019-06-15', 2),
('2019-06-16', NULL),
('2019-06-17', NULL),
('2019-06-18', 7),
('2019-06-19', 1),
('2019-06-20', 5),
('2019-06-21', NULL),
('2019-06-22', NULL),
('2019-06-23', NULL),
('2019-06-24', NULL),
('2019-06-25', 9),
('2019-06-26', 5),
('2019-06-27', 3),
('2019-06-28', 4),
('2019-06-29', NULL),
('2019-06-30', 1)
SELECT * FROM @Table
一种方法是使用 sub-select,选择当前 Date_D
.
你可以这样做
SELECT Date_D, CASE WHEN Val IS NULL THEN
(
SELECT TOP 1 Val
FROM @Table
WHERE Val IS NOT NULL AND Date_D < T.Date_D
ORDER BY Date_D DESC
) ELSE Val END
FROM @Table T;
如果您想更新 table 然后将其与结果结合起来。
对于UPDATE
;WITH CTE AS
(
SELECT Date_D, CASE WHEN Val IS NULL THEN
(
SELECT TOP 1 Val
FROM @Table
WHERE Val IS NOT NULL AND Date_D < T.Date_D
ORDER BY Date_D DESC
) ELSE Val END Val
FROM @Table T
)
UPDATE T
SET T.Val = CTE.Val
FROM @Table T INNER JOIN CTE
ON T.Date_D = CTE.Date_D
WHERE T.Val IS NULL; --You can also AND Date_D BETWEEN StartDate AND EndDate
看看它在 live demo
上是如何工作的使用相关子查询更新:
UPDATE T0
SET Val = (
SELECT TOP 1 Val
FROM @Table As T1
WHERE Val IS NOT NULL
AND T0.Date_D > T1.Date_D
ORDER BY Date_D DESC
)
FROM @Table As T0
WHERE Val IS NULL
验证:
SELECT *
FROM @Table
结果:
Date_D Val
15.06.2019 2
16.06.2019 2
17.06.2019 2
18.06.2019 7
19.06.2019 1
20.06.2019 5
21.06.2019 5
22.06.2019 5
23.06.2019 5
24.06.2019 5
25.06.2019 9
26.06.2019 5
27.06.2019 3
28.06.2019 4
29.06.2019 4
30.06.2019 1