sql 将两行合并到同一个表中。 (用第二行数据更新第一行,然后删除第二行)

标签 sql sql-server merge rows

我想将两行合并为一行,然后删除过时的行。 这是我的意思的一个小例子。

初始数据:

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/

相关文章:

mysql - 我无法在 mysql 中使用触发器更新我的表

MySQL更新和转换时区

c# - 分离本地数据库.mdf,复制,附加新文件

python - 基于列插值加入 Pandas

R:如何将两个 data.frame 合并为一个,匹配的 ID 重复自身,有时会丢失

mysql - 我怎样才能让这个选择查找另一个表并找到第一个匹配项?

sql - 如何从分组中计算总和值

sql - 修剪空白而不影响内部空白

sql - 获取多个通话的日期

Git - 由于 master 中的本地更改而 merge 时出错