[英]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.