4

我有一个包含 2 个字段(名称、兴趣)的表,我想找到所有具有相同兴趣的对,并删除所有重复项和镜像对。

我可以使用以下 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

3 回答 3

7

假设您不在乎哪一对最终坚持 (ben,will) 与 (will, 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.

于 2013-02-27T05:37:33.107 回答
3

我有类似的问题,并想出研究下面的查询会解决问题的第一个答案

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  
于 2014-05-06T11:48:14.910 回答
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)

所以而不是使用<>in

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

使用><运算符,它应该可以正常工作。

于 2013-02-27T05:34:54.250 回答