我想将两行合并为一行,然后删除过时的行。 这是我的意思的一个小例子。
初始数据:
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(Server 2012)
答案 0 :(得分:1)
在oracle的情况下使用子查询进行条件删除。
从tablename中删除(partA | partB)=(从表名中选择partA | partB)
答案 1 :(得分:1)
这解决了你的问题 - 可能会简化它,但我把它作为一个单一陈述的挑战。
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
没有覆盖非NULL
s,并且在两行都有数据的情况下,我们从我们正在删除的行中取值。
这可以通过在src
CTE中构造两行来实现 - 一行包含我们要删除的行中的所有数据,除了我们将数据复制到的行{{1} }列。第二行只包含要删除ID值的行。但是,名为ID
的新列中的行也不同,该列指示这是否是导致删除(Del
)或更新(1
)的行。
然后,在合并中,我们最终匹配两行,并使用0
列来决定要采取的操作。