我想将两行合并为一行,然后删除过时的行。 这是我的意思的一个小例子。
初始数据:
id | part A | part B
0 | OK | NULL
1 | NULL | OK
将 1 合并到 0,然后删除 1,结果如下。
id | part A | part B
0 | OK | OK
最好的办法是什么。一定有某种我忽略的合并/组合功能。
提前致谢。
PS。可能与此重复:possible duplicate 但并没有得到很好的答案。编辑: 我正在使用 MS SQL(服务器 2012)
最佳答案
这解决了您的问题 - 也许可以简化它,但我认为将其作为单个语句来完成是一个挑战。
declare @t table (id int not null, A varchar(20) null,
B varchar(19) null, C varchar(18) null)
//Sample data expanded from question
insert into @t (id,A,B,C) values
(0,'OKA',null,'Old'),
(1,null,'OKB','New')
//Input provided - @FromID is the row we'll delete
declare @FromID int
declare @ToID int
select @FromID = 1, @ToID = 0
//The actual query
;With src as (
select @ToID as ID,A,B,C,0 as Del from @t where id = @FromID
union all
select @FromID,null,null,null,1
)
merge into @t t
using (select ID,A,B,C,Del from src) s
on
t.ID = s.ID
when matched and Del = 0 then
update set
A = COALESCE(s.A,t.A),
B= COALESCE(s.B,t.B),
C = COALESCE(s.C,t.C)
when matched then
delete
;
//And show the final result
select * from @t
结果是:
id A B C
----------- -------------------- ------------------- ------------------
0 OKA OKB New
这表明 NULL
s 还没有覆盖非 NULL
并且,如果两行都有数据,我们就从要删除的行中获取值。
这通过在 src
中构造两行来实现。 CTE - 一行包含我们要删除的行中的所有数据,但我们要将数据复制到的行除外 ID
柱子。第二行仅包含要删除的行的 ID 值。但这些行在名为 Del
的新列中也有所不同。它指示这是否是导致删除 ( 1
) 或更新 ( 0
) 的行。
然后,在合并中,我们最终匹配两行并使用 Del
列来决定采取哪个操作。
关于sql 将两行合并到同一个表中。 (用第二行数据更新第一行,然后删除第二行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26230785/