簡體   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