2009-02-10 69 views
3

我需要將數據從一個表傳輸到另一個表。第二個表有一個主鍵約束(第一個表沒有約束)。它們具有相同的結構。我想是從表A中選擇所有的行和表B中沒有重複的行插入它(如果行IS0重複,我只想把我第一個發現)SQL - 僅選擇不重複的行

例子:

MyField1 (PK) | MyField2 (PK) | MyField3(PK) | MyField4 | MyField5 

---------- 

1    | 'Test'   | 'A1'   | 'Data1' | 'Data1' 
2    | 'Test1'   | 'A2'   | 'Data2' | 'Data2' 
2    | 'Test1'   | 'A2'   | 'Data3' | 'Data3' 
4    | 'Test2'   | 'A3'   | 'Data4' | 'Data4' 

就像你所看到的,第二行和第三行獲得了相同的PK鍵,但MyField4和MyField5中的數據不同。所以,在這個例子中,我想要第一,第二和第四行。不是第三個,因爲它是第二個的重複(即使MyField4和MyField5包含不同的數據)。

我怎樣才能做到這一點單選?

thx

+0

MySql,Oracle,MS Sql或其他? – BenMaddox 2009-02-10 00:52:44

回答

4

首先,您需要定義是什麼使行成爲「第一」。我將構建一個任意的定義,並且您可以根據需要更改SQL以滿足您的需求。對於這個例子,我假設「首先」是MyField4的最低值,如果它們相等,那麼MyField5的最低值。它也說明了所有5列相同的可能性。

SELECT DISTINCT 
    T1.MyField1, 
    T1.MyField2, 
    T1.MyField3, 
    T1.MyField4, 
    T1.MyField5 
FROM 
    MyTable T1 
LEFT OUTER JOIN MyTable T2 ON 
    T2.MyField1 = T1.MyField1 AND 
    T2.MyField2 = T1.MyField2 AND 
    T2.MyField3 = T1.MyField3 AND 
    (
      T2.MyField4 > T1.MyField4 OR 
      (
       T2.MyField4 = T1.MyField4 AND 
       T2.MyField5 > T1.MyField5 
     ) 
    ) 
WHERE 
    T2.MyField1 IS NULL 

如果你也想佔未在源表中重複的PK,而是已經存在於你的目標表,那麼你就需要考慮這一點。

2

什麼是您的數據庫?在Oracle中,您可以說

SELECT FROM your_table 
WHERE rowid in 
(SELECT MIN(rowid) 
FROM your_table 
GROUP BY MyField1, MyField2, MyField3); 

請注意,具有相同PK的哪些行將被視爲「第一個」是有些不確定的。如果您需要強制執行特定的訂單,則需要另外對其他列進行排序。

+0

這會爲your_table中的每一行運行一次嵌套的select語句嗎?如果可以的話,那麼你的表現會非常糟糕。 希望嵌套語句可以被緩存。不熟悉它的查詢計劃部分。 – Bassam 2009-02-10 01:20:46

+0

我使用MS SQL 2005,但我認爲這個語法會起作用,我會明天再試,然後我會通知你。謝謝! – Melursus 2009-02-10 01:22:20

3

不知道你是怎麼知道哪一行2和第3行,你在新表中想要的,但在MySQL中,你可以簡單地說:

insert ignore into new_table (select * from old_table); 

而且PK不會允許插入重複的條目。

0
CREATE TABLE #A(
ID INTEGER IDENTITY, 
[MyField1] [int] NULL, 
[MyField2] [varchar](10) NULL, 
[MyField3] [varchar](10) NULL, 
[MyField4] [varchar](10) NULL, 
[MyField5] [varchar](10) NULL 
) 

INSERT INTO #A (MyField1,MyField2,MyField3,MyField4,MyField5) SELECT * FROM A 

insert into B 
    select MyField1,MyField2,MyField3,MyField4,MyField5 from #A a1 
    where not exists (select id from #A a2 where a2.MyField1 = a1.MyField1 and a2.ID < a1.ID) 

DROP TABLE #A 

OR

insert into b 
    select distinct * from a a1 
    where not exists (
    select a2.MyField1 from a a2 where a1.MyField1 = a2.MyField1 and 
     (a1.MyField2 < a2.MyField2 or a1.MyField3 < a2.MyField3 
     or a1.MyField4 < a2.MyField5 or a1.MyField5 < a2.MyField5)) 
1

這取決於你在找什麼。

有使用JOIN + WHERE NULLNOT INNOT EXISTS,包括性能,這是更大的數據集更重要的一個很大的區別。

(參見NOT IN vs. NOT EXISTS vs. LEFT JOIN/IS NULL。)

鏈接本文中顯示的三種方法是非常簡單的。