[英]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;
您的数据中有重复项。 在MERGE
的ON
子句中添加另一(或不止一个)列,这将有助于准确识别一条记录或找到一种在合并之前删除重复项的方法。
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'
由于我们仅使用SourceTbl
中Block
为1
的行,因此受此更新影响的行不可能以Block
为0
的原因结束。
仍然存在一个普遍的问题,即在将SourceTbl
中的多行连接到SourceTbl
中的一行的情况下,这是不TargetTbl
,但是由于您已经表明此处不需要确定性,因此这不会导致问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.