【问题标题】:sql merge two rows into one, same table. (update 1st with 2nd row data, then delete 2nd row)sql 将两行合并为同一张表。 (用第二行数据更新第一行,然后删除第二行)
【发布时间】:2014-12-01 13:43:31
【问题描述】:

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

初始数据:

id | part A | part B
0  |  OK    |  NULL
1  | NULL   |  OK

将 1 合并为 0,然后删除 1,结果如下。

id | part A | part B
0  |  OK    |  OK

什么是最好的方法。我忽略了某种合并/组合功能。

提前致谢。

附言。可能与此重复:possible duplicate 但它没有得到好的答案。

编辑: 我正在使用 MS SQL (Server 2012)

【问题讨论】:

  • ID=0 的行和 ID=1 的行有什么关系?
  • 没有关系。用户有两条损坏的记录,应该是一条记录。用户必须首先使用有根据的猜测并选择两条记录合并为一条记录,这可能会覆盖某些数据。所以我需要的是关于如何将两条记录合并为一条的声明(由用户在 id 上选择)
  • 所以,关系是有人给了我们两个特定的ID 值。其他列值应该从较高的ID行复制到较低的ID行,然后应该删除较高的ID行?两行应该发生什么在同一列中有非NULL数据(或者这种情况不会发生)?
  • 正如我之前的评论所说:可能会覆盖一些数据。允许覆盖数据。用户指定要组合的两个 id,第二个到第一个。覆盖数据几乎总是会发生,但这是允许和期望的。但是不能复制 NULL 值。

标签: sql sql-server merge rows


【解决方案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

这表明NULLs 没有覆盖非NULLs,并且在两行都有数据的情况下,我们从要删除的行中获取了值。


这通过在src CTE 中构造两行来工作 - 一行包含我们要删除的行中的所有数据,除了我们将数据复制到的行作为其ID 列。第二行只包含要删除的 ID 值的行。但是这些行在名为Del 的新列中也有所不同,该列指示这是导致删除 (1) 还是更新 (0) 的行。

然后,在合并中,我们最终匹配两行并使用 Del 列来决定要采取的操作。

【讨论】:

  • 这正是我想要和需要的。非常感谢!
【解决方案2】:

在 oracle 的情况下,使用子查询进行条件删除。

delete from tablename where (partA|partB)=(select partA| partB from tablename)

【讨论】:

  • 我已经编辑了我的帖子。我正在使用 ms sql 来具体
  • delete from tablename where Concat(partA,partB)=(select Concat(partA, partB) from tablename) ,试试这个
  • 这如何将两条记录合并为一条记录,留下一条完整的记录?
  • 关于这个解决方案应该如何工作以及结果如何的任何解释?我不明白,因为我对此比较陌生。
  • 有两个查询,第一个在等号(=)之前称为外部查询,第二个在括号()内的等号之后称为内部查询。首先内部查询将执行并在等号后替换返回值,外部查询是条件删除查询它只会删除满足条件的记录。
猜你喜欢
  • 1970-01-01
  • 2014-01-30
  • 2014-01-25
  • 1970-01-01
  • 2020-08-09
  • 2022-08-02
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多