2012-08-30 107 views
3

以下是我想要的: 將tableA複製到tableB,但不復制已經在tableB中的任何行。沒有PK或標識,我只是想檢查每個字段,並且如果有與所有相同字段匹配的行,則不要插入。我試着用INSERT和MERGE:跳過/忽略/不插入重複行

--try with INSERT 
INSERT TableB(col1,col2,col3,col4,col5,col6, etc.) 
SELECT (col1,col2,col3,col4,col5,col6, etc.) 
FROM tableA as src 
WHERE NOT EXISTS (SELECT 1 FROM TableB as T 
      WHERE    
      T.col1 = src.col1 AND 
      T.col2 = src.col2 AND 
      T.col3 = src.col3 AND 
      T.col4 = src.col4 AND 
      T.col5 = src.col5 AND 
      T.col6 = src.col6, etc.) 

我也試過用MERGE:

MERGE INTO tableA src 
    USING tableB T 
    ON (
      T.col1 = src.col1 AND 
      T.col2 = src.col2 AND 
      T.col3 = src.col3 AND 
      T.col4 = src.col4 AND 
      T.col5 = src.col5 AND 
      T.col6 = src.col6, etc.) 
    WHEN NOT MATCHED THEN 
    INSERT (col1,col2,col3,col4,col5,col6, etc.) 
    VALUES (col1,col2,col3,col4,col5,col6, etc.); 

兩個做同樣的事情:我會做插件(或合併)並且最初所有的行都被導入,這很好,但是在第二次嘗試時(應該插入/合併0行),它將插入/合併60%的行。

我相信這個問題是因爲我沒有PK,這是我在其他帖子上看到的。我只想匹配所有領域,這可能嗎?我錯過了什麼嗎?

感謝您的任何建議/方向!

+0

使用光標或遞歸函數這可能會幫助你 –

+0

@AnantDabhi - 光標是這個 – LittleBobbyTables

+0

感謝完全矯枉過正爲了幫助我.. –

回答

6

您可以使用EXCEPT

INSERT INTO table1 
SELECT * from table2 
EXCEPT 
SELECT * from table1; 

看一看小提琴here

+0

超越真棒!我不知道EXCEPT命令。奇蹟般有效! – russds

+0

謝謝。我來自Oracle,我們一直使用MINUS,但是我搜索了一下,發現SQL Server的等價物叫做EXCEPT。所以我想我必須回答。爲了確保我嘗試了一下小提琴,這是一種很好的方式來測試數據庫系統的SQL語句,這是人們不熟悉的。 – hol

2

您可以使用LEFT OUTER JOIN在SELECT語句查找記錄,所有列NULL,就像這樣:

INSERT INTO tableB (col1,col2,col3,col4,col5,col6, etc.) 
SELECT (A.col1, A.col2, A.col3, A.col4, A.col5, A.col6, etc.) 
FROM tableA as A 
LEFT OUTER JOIN tableB AS B ON A.col1 = B.col1 AND A.col2 = B.col2 AND 
    A.col3 = B.col3 ... /* all the way to B.col99 or whatever */ 
WHERE B.col1 IS NULL AND B.col2 IS NULL AND B.col3 IS NULL ... 
    /* all the way to B.col99 or whatever your last column is */ 
+0

使用'MERGE'可能會有一種更清晰的方式,但我對此很生疏,而且必須考慮更多。 – LittleBobbyTables

2

我的猜測是,這個問題是NULL值。嘗試查詢爲:

INSERT TableB(col1,col2,col3,col4,col5,col6, etc.) 
SELECT (col1,col2,col3,col4,col5,col6, etc.) 
FROM tableA as src 
WHERE NOT EXISTS (SELECT 1 FROM TableB as T 
        WHERE (T.col1 = src.col1 or t.col1 is null and src.col1 is null) AND 
         (T.col2 = src.col2 or t.col2 is null and src.col2 is null) AND 
         . . . 
+0

謝謝,我也懷疑NULL是造成這個問題。 @hol的EXCEPT命令考慮到了這一點,並且效果很好。 – russds

+0

@russds。 。 。該解決方案要簡單得多。很高興知道它的作品。 –

0

您的問題可能與NULL值有關。以下腳本確保如果存在具有一些NULL列的現有行,則它們是匹配的。

--Create the sample source table. 
--Notice that the columns allow NULL values... 
CREATE TABLE #T1 
(
    Col1 nvarchar(10) NULL, 
    Col2 nvarchar(10) NULL, 
    Col3 nvarchar(10) NULL 
) 

--Create the sample destination table. 
CREATE TABLE #T2 
(
    Col1 nvarchar(10) NULL, 
    Col2 nvarchar(10) NULL, 
    Col3 nvarchar(10) NULL 
) 
GO 
--Populate the source table with some initial rows 
--Notice that some column values are NULL 
INSERT INTO #T1 (Col1,Col2,Col3) 
VALUES ('A','B',NULL), 
     ('D','E','F'),  
     ('G',NULL,'I'); 
GO 
--Verify the data in the tables 
--Table #T1 should have data in it 
SELECT * FROM #T1; 
--Table #T2 should be empty 
SELECT * FROM #T2; 
GO 
--Copy the rows from #T1 to #T2 
--where there are no matching rows. 
INSERT INTO #T2(Col1,Col2,Col3) 
SELECT 
    T1.Col1,T1.Col2,T1.Col3 
FROM #T1 AS T1 
LEFT OUTER JOIN #T2 AS T2 
ON IsNull(T1.Col1,'') = IsNull(T2.Col1,'') 
AND IsNull(T1.Col2,'') = IsNull(T2.Col2,'') 
AND IsNull(T1.Col3,'') = IsNull(T2.Col3,'') 
WHERE T2.Col1 IS NULL AND T2.Col2 IS NULL AND T2.Col3 IS NULL 
GO 
--Verify the data in the tables. They should be the same now. 
SELECT * FROM #T1; 
SELECT * FROM #T2; 
GO 
--Add a some new rows to #T1 
INSERT INTO #T1 (Col1,Col2,Col3) 
VALUES ('J','K','L'), 
     ('M',NULL,'O'), 
     ('P','Q','R'), 
     ('A','B','C'); --THIS LAST ROW DOES NOT MATCH THE EXISTING A,B,NULL ROW AND WILL BE INSERTED ON MERGE 
GO 
--Merge the tables, and yes you could use MERGE where the ON clause handled NULLs 
INSERT INTO #T2(Col1,Col2,Col3) 
SELECT 
    T1.Col1,T1.Col2,T1.Col3 
FROM #T1 AS T1 
LEFT OUTER JOIN #T2 AS T2 
ON IsNull(T1.Col1,'') = IsNull(T2.Col1,'') 
AND IsNull(T1.Col2,'') = IsNull(T2.Col2,'') 
AND IsNull(T1.Col3,'') = IsNull(T2.Col3,'') 
WHERE T2.Col1 IS NULL AND T2.Col2 IS NULL AND T2.Col3 IS NULL 
GO 
--Verify the new data is in both tables. 
SELECT * FROM #T1; 
SELECT * FROM #T2; 
GO 
--Cleanup 
DROP TABLE #T1; 
DROP TABLE #T2; 
+1

儘管您的解決方案確實解決了兩個列中的NULL不被視爲「相等」的問題,但您會引入一個與NULL相同的空字符串的新問題。 –