2017-06-19 19 views
0

SQL SERVER 2014UPDATE 2列使用具有源條件MERGE

我需要從sourceTable會

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

TargetTable

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

與值來更新TargetTable兩列需要的結果:

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

​​人1獲得 只要它是從Block ='1'的行中的一個是無關的。

我已經試過這非常直接的更新:

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' 

但結束了錯誤的結果,行,其中塊和原因分別更新:

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.

任何幫助?非常感謝!真正做到。完全。

+0

你'UPDATE'看起來* *一般正確的,除了與源和目標困惑。 (應該是有針對性的,好的,目標,但仍然是正確的諮詢源塊列) –

+0

@Kaptah表的主鍵是什麼? –

回答

0

您的數據有重複。在MERGEON子句中添加另一個(或多個)列,這將有助於準確識別一條記錄或找到合併前刪除重複項的方法。

0

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其中Block1行,它不應該受此影響的更新行落得可能原因是Block0

仍有普遍的問題,這是案件不確定性,其中來自SourceTbl多行TargetTbl被連接到一排,但因爲你已經表示,決定在這裏不需要,它不應該導致在一個問題。

1

與您的查詢的問題是,它提供重複的值,它試圖不止一次地更新相同的記錄。並且子查詢中的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 2次,每次只記錄一次。

你可以試試下面的查詢:

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; 
+1

嘗試更正:'FROM SourceTbl)X WHERE X.RN = 1'。似乎工作:) – Kaptah

+0

@Kaptah對不起..那是一個錯字..沒有'WHERE'.Thanks指出。更新我的答案。 –