我有一个包含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);
但它不会删除所有镜像对。
答案 0 :(得分:5)
假设你不关心哪一对最终坚持(ben,will)vs(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
相同的模式而不是{{1 }}
答案 1 :(得分: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
答案 2 :(得分: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);)
使用>
或<
运算符,它应该可以正常工作。