2013-02-27 37 views
3

我有一個包含2個字段(名稱,興趣)的表,我想找到所有具有相同興趣的對,並刪除所有重複項和鏡像對。從SQL中刪除鏡像對加入

我能找到的所有對,並與下面的SQL語句刪除重複:

SELECT P1.name AS name1, P2.name AS name2, P1.interest 
FROM Table AS P1, Table AS P2 
WHERE P1.interest = P2.interest AND P1.name <> P2.name; 

但我不知道如何刪除鏡像對,即:

"wil","ben","databases"

"ben","wil","databases"

我試圖讓上面的語句成爲一個叫Matches的視圖,並嘗試了下面的查詢:

SELECT * FROM Matches 
WHERE name2 <> (select name1 from Matches); 

但它不會刪除所有鏡像對。

回答

4

假設你沒有關心哪對最終粘周圍(BEN,會)VS(會,BEN),那麼我的優選的解決方案是執行以下操作:

DELETE p2 
FROM Pairs p1 
INNER JOIN Pairs p2 
    on p1.Name1 = p2.Name2 
    and p1.Name2 = p2.Name1 
    and p1.Interest = p2.Interest 
    -- match only one of the two pairs 
    and p1.Name1 > p1.Name2 

憑藉這一事實你永遠不會有Name1和Name2相等,必須總是有一對,第一個成員小於第二個成員。使用這種關係,我們可以刪除重複。

如果您有關係的代理關鍵字,這是特別微不足道的,因爲那樣對Name1和Name2的要求是不相等的消失。

編輯:如果你不想從表中刪除,而只是從特定查詢的結果,使用相同的圖案SELECT而非DELETE

+1

@wilco,從性能甚至查詢計劃中使用ANSII連接與笛卡爾產品無關。不同之處在於可維護性,但它非常主觀。見http://www.orafaq.com/node/2618。就性能而言,它將取決於您正在使用的RDBMS。有些人可能會將其作爲子查詢執行,在N1中每行執行一次,而不是實現一個視圖並對該視圖執行映射。 – Mitch 2013-02-27 05:58:50

+1

@wilco,把一些數字加入Subquery vs Join,看看這個URL:http://jahaines.blogspot.com/2009/06/correlated-sub-queries-for-good-or-evil.html它討論了對SQL Server的影響具體並概述了相關子查詢的危險性。 – Mitch 2013-02-27 06:02:08

+0

謝謝,米奇!我真的很感激額外的信息 – wilco 2013-02-27 06:26:48

2

假設我們有一個表Name與元組:

F1 F2   
Jon Smith   
Smith Jon 

然後刪除這對我們可以讓這樣的查詢:

SELECT n1.F1, n1.F2   
FROM Name n1    
WHERE n1.F1 > (SELECT n2.F1 
        FROM Name n2 
        WHERE n1.F1=n2.F2) 

所以不是在

(SELECT * FROM Matches 
WHERE name2 **<>** (select name1 from Matches);) 
使用 <>

使用><運營商它應該工作得很好。

+0

謝謝!這很好!你碰巧知道這個關係代數的等價物嗎?我不想完全理解這個問題。 – wilco 2013-02-27 05:41:52

+0

我現在不知道,但我會盡量做出一個。我也想用一些不同的方式來解決它。如果您找到其他解決方案,請更新。 – ritesh 2013-02-27 05:45:32

2

我有類似的問題,並找出學習的第一個答案是下面的查詢就可以了

SELECT P1.name AS name1,P2.name AS name2,P1.interest 
FROM Table AS P1,Table AS P2 
WHERE P1.interest=P2.interest AND P1.name>P2.name