繁体   English   中英

使用具有源条件的MERGE更新2列

[英]UPDATE 2 columns using MERGE having source conditions

SQL服务器2014

我需要使用SourceTable中的值更新TargetTable中的两列

SourceTbl

PersonNr |   Block  |   BlockReason |
---------|----------|---------------|
000001   |   1      |   abuse       | 
000001   |   1      |   age         | 
000001   |   0      |   memo        | 
000002   |   1      |   age         | 
000002   |   0      |               | 
000003   |   0      |               | 
000003   |   0      |               | 
000004   |   1      |   behaviour   | 
000005   |   0      |               | 

目标表

PersonNr |   Block  |   BlockReason |
---------|----------|---------------|
000001   |   0      |               | 
000001   |   0      |               | 
000002   |   0      |               | 
000002   |   0      |               | 
000004   |   1      |               | 
000005   |   0      |               | 

需要的结果:

PersonNr |   Block  |   BlockReason |
---------|----------|---------------|
000001   |   1      |   abuse       | 
000001   |   1      |   abuse       | 
000002   |   1      |   age         | 
000002   |   1      |   age         | 
000004   |   1      |   behaviour   |
000005   |   0      |               | 

至于BlockReason Person 1所获得的信息,与Block ='1'的BlockReason无关。

我已经尝试了这个非常简单的更新:

UPDATE
    src
SET
    src.Block = '1', 
    src.BlockReason = targ.BlockReason
FROM
    SourceTbl src
INNER JOIN
    TargetTable targ
ON 
    src.PersonNr= targ.PersonNr
WHERE src.Block = '1'

但最终导致错误的结果行,其中Block和Reason分别更新:

PersonNr |   Block  |   BlockReason |
---------|----------|---------------|
000001   |  1       |   memo        | 

接下来,我尝试了:

MERGE INTO TargetTable AS TGT
USING
(
  SELECT Block, BlockReason, PersonNr
  FROM SourceTbl
 GROUP BY Block, BlockReason, PersonNr
) AS SRC
  ON 
    SRC.PersonNr= TGT.PersonNr AND 
    SRC.Block= '1' 
WHEN MATCHED THEN
UPDATE SET TGT.Block= SRC.Block, TGT.BlockReason= SRC.BlockReason;

得到了错误

The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.

有什么帮助吗? 非常感谢! 真的 完全。

您的查询的问题在于它提供重复的值,并且试图多次更新同一条记录。由于您没有使用任何聚合函数,因此子查询中的GROUP BY没有任何意义。

让我们以一个id(例如1)检查您的查询出了什么问题。

src.PersonNr |   src.Block  |   src.BlockReason | tgt.PersonNr |   tgt.Block  |   tgt.BlockReason |
-------------|--------------|-------------------|--------------
    000001   |   1          |   abuse           | 000001       |       0      |                   |         
    000001   |   1          |   age             | 000001       |       0      |                   | 
    000001   |   1          |   abuse           | 000001       |       0      |                   |
    000001   |   1          |   age             |  000001      |       0      |                   |

您的查询将为您提供上述结果,并尝试针对每条记录两次更新targettable一次,一次滥用,另一次随着年龄增长。

您可以尝试以下查询:

MERGE INTO TargetTable AS TGT
USING
(
 SELECT Block, BlockReason, PersonNr
 FROM(
       SELECT Block, BlockReason, PersonNr,ROW_NUMBER() OVER (PARTITION BY PersonNr  ORDER BY [YourPrimaryKey]) RN
       FROM SourceTbl ) X
 WHERE X.RN=1
) AS SRC
  ON 
    SRC.PersonNr= TGT.PersonNr AND 
    SRC.Block= '1' 
WHEN MATCHED THEN
UPDATE SET TGT.Block= SRC.Block, TGT.BlockReason= SRC.BlockReason;

您的数据中有重复项。 MERGEON子句中添加另一(或不止一个)列,这将有助于准确识别一条记录或找到一种在合并之前删除重复项的方法。

UPDATE应该是这样的:

UPDATE
    targ
SET
    Block = '1', 
    BlockReason = src.BlockReason
FROM
    SourceTbl src
INNER JOIN
    TargetTable targ
ON 
    src.PersonNr= targ.PersonNr
WHERE src.Block = '1'

由于我们仅使用SourceTblBlock1的行,因此受此更新影响的行不可能以Block0的原因结束。

仍然存在一个普遍的问题,即在将SourceTbl中的多行连接到SourceTbl中的一行的情况下,这是不TargetTbl ,但是由于您已经表明此处不需要确定性,因此这不会导致问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM