Sha*_*awn 3 sql sql-server loops sql-update
我有一个类似于以下的SQL表:
ID, Date, D1, D2, D3
1 1/1/13 0 X A
2 1/2/13
3 1/3/13 1
4 1/4/13 B
5 1/5/13
Run Code Online (Sandbox Code Playgroud)
我需要更新到以下内容:
ID, Date, D1, D2, D3
1 1/1/13 0 X A
2 1/2/13 0 X A
3 1/3/13 1 X A
4 1/4/13 1 X B
5 1/5/13 1 X B
Run Code Online (Sandbox Code Playgroud)
基本上用前面的值填充所有空值.这只会执行一次.循环是最好的选择吗?还是有更有效的东西?
假设你正在使用SQL-Server,你可以使用这个common-table-expression:
WITH cte
AS (SELECT T1.id,
T1.date,
d1 = COALESCE(T1.d1, (SELECT TOP 1 d1
FROM dbo.tablename T2
WHERE T2.id < T1.id
AND d1 IS NOT NULL
ORDER BY id DESC)),
d2 = COALESCE(T1.d2, (SELECT TOP 1 d2
FROM dbo.tablename T2
WHERE T2.id < T1.id
AND d2 IS NOT NULL
ORDER BY id DESC)),
d3 = COALESCE(T1.d3, (SELECT TOP 1 d3
FROM dbo.tablename T2
WHERE T2.id < T1.id
AND d3 IS NOT NULL
ORDER BY id DESC))
FROM dbo.tablename T1)
UPDATE T
SET T.d1 = C.d1,
T.d2 = C.d2,
T.d3 = C.d3
FROM dbo.tablename T
INNER JOIN cte C
ON T.id = C.id
WHERE T.d1 IS NULL
OR T.d2 IS NULL
OR T.d3 IS NULL
Run Code Online (Sandbox Code Playgroud)
编辑因为您在评论中提到过,''而不是null,这是一个支持两者的修改版本:
WITH cte AS
(SELECT T1.id,
T1.date,
d1 = CASE WHEN COALESCE(T1.d1, '') <> '' THEN d1
ELSE(SELECT TOP 1 d1
FROM dbo.tablename T2
WHERE T2.id < T1.id
AND COALESCE(T2.d1, '') <> ''
ORDER BY T2.id DESC) END,
d2 = CASE WHEN COALESCE(T1.d2, '') <> '' THEN d2
ELSE(SELECT TOP 1 d2
FROM dbo.tablename T2
WHERE T2.id < T1.id
AND COALESCE(T2.d2, '') <> ''
ORDER BY T2.id DESC) END,
d3 = CASE WHEN COALESCE(T1.d3, '') <> '' THEN d3
ELSE(SELECT TOP 1 d3
FROM dbo.tablename T2
WHERE T2.id < T1.id
AND COALESCE(T2.d3, '') <> ''
ORDER BY T2.id DESC) END
FROM dbo.tablename T1)
UPDATE T
SET T.d1 = C.d1,
T.d2 = C.d2,
T.d3 = C.d3
FROM dbo.tablename T
INNER JOIN cte C
ON T.id = C.id
WHERE COALESCE(T.d1, '') = ''
OR COALESCE(T.d2, '') = ''
OR COALESCE(T.d3, '') = ''
Run Code Online (Sandbox Code Playgroud)