2015-10-27 50 views
0

我有兩個具有相同結構t1和t2的表。
表t1比t2有大約100多條記錄。使用T-SQL合併更新現有記錄並插入不存在但避免重複的記錄

這裏有一個t1的小樣本。

| pid | tid | amt   | paymentdt | paymentmnth | startdate     | enddate     | updtby 
| 670 | 1  | 690.00  | 2015-07-07 | 2015-07-07 | 2015-10-26 14:36:27.000 | 2015-10-26 15:42:42.000 | NULL 
| 670 | 11  | 855.00  | 2015-07-07 | 2015-07-07 | 2015-10-26 14:36:27.000 | NULL      | NULL 
| 670 | 13  | 129.00  | 2015-07-29 | 2015-07-29 | 2015-10-26 14:36:27.000 | NULL      | NULL 
| 670 | 2  | 855.00  | 2015-09-01 | 2015-09-01 | 2015-10-26 15:42:42.000 | NULL      | NULL 
| Z41 | 1  | 62.35  | 2015-05-08 | 2015-05-08 | 2015-10-26 10:15:24.000 | 2015-10-26 13:08:05.000 | NULL 
| Z41 | 11  | 800.00  | 2015-05-08 | 2015-05-08 | 2015-10-26 10:15:24.000 | NULL      | NULL 
| Z41 | 2  | 298.00  | 2015-06-01 | 2015-06-01 | 2015-10-26 13:08:05.000 | 2015-10-26 14:36:27.000 | NULL 
| Z41 | 3  | 298.00  | 2015-07-01 | 2015-07-01 | 2015-10-26 14:36:27.000 | 2015-10-26 15:15:45.000 | NULL 
| Z41 | 4  | 298.00  | 2015-08-01 | 2015-08-01 | 2015-10-26 15:15:45.000 | 2015-10-26 15:42:42.000 | NULL 
| Z41 | 5  | 238.00  | 2015-09-01 | 2015-09-01 | 2015-10-26 15:42:42.000 | NULL      | NULL 

和t2的小樣本。

| pid | tid | amt   | paymentdt | paymentmnt | startdate     | enddate     | updtby 
| 670 | 1  | 690.00  | 2015-07-07 | 2015-07-07 | 2015-10-02 16:10:50.000 | 2015-10-02 16:35:50.000 | NULL 
| 670 | 11  | 855.00  | 2015-07-07 | 2015-07-07 | 2015-10-02 16:10:50.000 | NULL      | NULL 
| 670 | 13  | 129.00  | 2015-07-29 | 2015-07-29 | 2015-10-02 16:10:50.000 | NULL      | NULL 
| 670 | 2  | 855.00  | 2015-09-01 | 2015-09-01 | 2015-10-02 16:35:50.000 | NULL      | NULL 
| Z41 | 1  | 298.00  | 2015-07-01 | 2015-07-01 | 2015-10-02 16:10:50.000 | 2015-10-02 16:23:26.000 | NULL 
| Z41 | 11  | 800.00  | 2015-05-08 | 2015-05-08 | 2015-10-02 16:10:50.000 | NULL      | NULL 
| Z41 | 2  | 298.00  | 2015-08-01 | 2015-08-01 | 2015-10-02 16:23:26.000 | 2015-10-02 16:35:50.000 | NULL 
| Z41 | 3  | 238.00  | 2015-09-01 | 2015-09-01 | 2015-10-02 16:35:50.000 | NULL      | NULL 
| 173 | 1  | 785.00  | 2015-07-01 | 2015-07-01 | 2015-10-02 16:16:30.000 | 2015-10-02 16:27:36.000 | NULL 
| 173 | 11  | 465.00  | 2015-05-01 | 2015-05-01 | 2015-10-02 16:16:30.000 | NULL      | NULL 

現在比較t1和t2示出了有在T1更多的值的PID Z41如TID的包括1,2,3,4 5,和11,但在t2中僅存在1,2,3 ,和11.

但是,t1和t2之間的startdate是完全不同的,所以這會引發一些問題。下面是我嘗試過的合併,但它基本上只是在t2中插入每行都與t1不同的startdate。

MERGE INTO t2 AS tgt 
USING t1 AS src 
    ON tgt.pid = src.pid AND 
     tgt.tid = src.tid AND 
     tgt.paymentdt = src.paymentdt AND 
     tgt.paymentmnt = src.paymentmnt AND 
     tgt.startdate = src.startdate 
WHEN MATCHED THEN 
    UPDATE SET 
     tgt.amt = src.amt, 
     tgt.paymentdt = src.paymentdt, 
     tgt.updatedby = 'MERGEDUPDATE' 
WHEN NOT MATCHED THEN 
    INSERT (pid, tid, amt, paymentdt, paymentmnt, startdate, enddate, updtby) 
    VALUES (src.pid, src.tid, src.amt, src.paymentdt, src.paymentmnt, src.startdate, src.enddate, 'MERGEDINSERT'); 

有了這個合併我留下的pid and tid其中updtby欄寫着「MERGEDINSERT」重複。但我想避免重複。

如何正確地去了解這個合併不產生重複,但 插入存在於T1而不是T2中的行,同時更新 amt, paymentdt, and paymentmnth值,同時保持STARTDATE?

+0

可能被刪除日期和ON子句的數量?您所顯示的數據的期望輸出是什麼? –

回答

0

您描述的方式,您的合併標準應該僅基於pidtid。試試這個

MERGE INTO t2 AS tgt 
USING t1 AS src 
    ON tgt.pid = src.pid AND 
     tgt.tid = src.tid 

WHEN MATCHED THEN 
    UPDATE SET 
     tgt.amt = src.amt, 
     tgt.paymentdt = src.paymentdt, 
     tgt.paymentmnth = src.paymentmnth, 
     tgt.updatedby = 'MERGEDUPDATE' 
WHEN NOT MATCHED THEN 
    INSERT (pid, tid, amt, paymentdt, paymentmnt, startdate, enddate, updtby) 
    VALUES (src.pid, src.tid, src.amt, src.paymentdt, src.paymentmnt, src.startdate, src.enddate, 'MERGEDINSERT'); 
+0

在'on'子句中只保留'pid'和'tid'會產生以下結果:'MERGE語句試圖多次更新或刪除同一行。當目標行匹配多個源行時會發生這種情況。 MERGE語句不能多次更新/刪除目標表的同一行。細化ON子句以確保目標行最多匹配一個源行,或者使用GROUP BY子句對源行進行分組。# – gh0st

+0

@ gh0st這意味着您獲得了多個匹配'pid/tid'組合的匹配項。什麼是期望的輸出?你可以在日期使用MAX()嗎? –

+0

基本上,我想更新t2中的任何記錄與t1中的匹配記錄,如果不存在'pid + tid'組合記錄我想插入它。 – gh0st

0

如果你MERGE,是因爲越來越多條記錄/匹配的拋出一個錯誤,你可以使用子查詢中聚集限制的源表,例如:

;WITH t1cte AS (
    select pid, tid, amt, paymentdt, paymentmnt, startdate, enddate 
    from t1 a 
     inner join (select pid,tid,MAX(paymentdt) as maxdt from t1 group by pid,tid) b 
     on a.pid = b.pid and a.tid = b.tid and a.paymentdt = b.maxdt 
     ) 

MERGE INTO t2 AS tgt 
USING t1cte AS src 
    ON tgt.pid = src.pid AND 
     tgt.tid = src.tid AND 
     tgt.paymentdt = src.paymentdt AND 
     tgt.paymentmnt = src.paymentmnt AND 
     tgt.startdate = src.startdate 
WHEN MATCHED THEN 
    UPDATE SET 
     tgt.amt = src.amt, 
     tgt.paymentdt = src.paymentdt, 
     tgt.updatedby = 'MERGEDUPDATE' 
WHEN NOT MATCHED THEN 
    INSERT (pid, tid, amt, paymentdt, paymentmnt, startdate, enddate, updtby) 
    VALUES (src.pid, src.tid, src.amt, src.paymentdt, src.paymentmnt, src.startdate, src.enddate, 'MERGEDINSERT'); 
+0

'列'dbo.t1.pid'在選擇列表中是無效的,因爲它不包含在任何一個一個聚合函數或GROUP BY子句。' – gh0st

+0

將'inner join()'中的'select'更改爲'pid,tid'將t1,pid,tid,max(paymentdt)選擇爲maxdt。 – gh0st

+0

但是仍然插入重複項,因爲'tgt.startdate = src.startdate'上沒有匹配項。 – gh0st

相關問題