2016-01-06 69 views
0

如何刪除具有相同Letter的反轉(m,n)<→(n,m)?刪除具有相同第三列值的反轉元組

Table 
id1;id2;Letter 
1;2;"A" 
3;4;"B" 
4;3;"B" -> row to be deleted or the one above(3;4;"B"), no matter which one 
5;6;"C" 
6;5;"C" -> row to be deleted or the one above(5;6;"C"), no matter which one 
1;2;"B" 

謝謝大家

+0

如果'id1' ='id2'? –

回答

0

另一種方法來做到這一點刪除是:

delete 
    from table t 
     USING table t2 
where t.id1 > t.id2 
    and t.id1 = t2.id2 
    and t.id2 = t2.id1 
    and t.Letter = t2.Letter; 

您還應該考慮添加兩個驗證約束和索引以防止su CH情況再次發生:

alter table table add constraint chk_diff_ids CHECK (id1 != id2); 

CHECK CONSTRAINT將避免ID1 beeing插入等於ID2像1;1;'A'

CREATE UNIQUE INDEX idx_reverse_value 
    ON table (Letter, LEAST(id1,id2), GREATEST(id1,id2)); 

該指數會阻止創建一個反轉的值作爲要刪除的話,所以如果你有1,2,'B'它會阻止插入2,1,'B'

注意:table是一個保留字,你不應該使用它作爲表名:)

看到它在這裏工作的小提琴:http://sqlfiddle.com/#!15/17f00/2

1

假設這個語法同樣適用於PostgreSQL的(我沒有在幾年內與它的工作)

DELETE MT 
FROM 
    My_Table MT 
WHERE 
    MT.id1 > MT.id2 AND 
    EXISTS 
    (
     SELECT * 
     FROM 
      My_Table MT2 
     WHERE 
      MT2.id1 = MT.id2 AND 
      MT2.id2 = MT.id1 AND 
      MT2.letter = MT.letter -- If this is also part of the requirement, otherwise you need logic on which row to keep 
    ) 
+0

是的它的工作原理,我只需要在第二個地方使用「!=」而不是「=」來獲得沒有壞行的行。非常感謝您的回覆 –

相關問題