我继承了一个数据库,其中包含一个查找表,用于查找与给定专利相关的其他专利。
看起来像
╔════╦═══════════╦════════════╗
║ id ║ patent_id ║ related_id ║
╠════╬═══════════╬════════════╣
║ 1 ║ 1 ║ 2 ║
║ 2 ║ 1 ║ 3 ║
║ 3 ║ 2 ║ 1 ║
║ 4 ║ 2 ║ 3 ║
║ 5 ║ 3 ║ 2 ║
╚════╩═══════════╩════════════╝
而且我想过滤掉互惠关系。 1->2 和 2->1 对我来说是一样的,所以我只想要 1->2。
我不需要在表格中进行编辑,我只需要一个返回唯一关系列表的查询,虽然我确信这很简单,但我一直在敲键盘太长。
最佳答案
这是一个您可以尝试使用的巧妙查询。一般策略是识别不需要的重复记录,然后从整个集合中减去它们。
SELECT t.id, t.patent_id, t.related_id
FROM t LEFT JOIN
(
SELECT t1.patent_id AS t1_patent_id, t1.related_id AS t1_related_id
FROM t t1 LEFT JOIN t t2
ON t1.related_id = t2.patent_id
WHERE t1.patent_id = t2.related_id AND t1.patent_id > t1.related_id
) t3
ON t.patent_id = t3.t1_patent_id AND t.related_id = t3.t1_related_id
WHERE t3.t1_patent_id IS NULL
这是这个查询生成的内部临时表。您可以说服自己,通过应用 WHERE
子句中的逻辑,您将选择正确的记录。非重复记录的特征是t1.patent_id
!= t2.related_id
,这些记录全部保留。对于重复项 (t1.patent_id
= t2.related_id
),从每对重复项中选择的记录是 patent_id
<related_id
,如您在问题中所要求的那样。
╔════╦══════════════╦═══════════════╦══════════════╦═══════════════╗
║ id ║ t1.patent_id ║ t1.related_id ║ t2.patent_id ║ t2.related_id ║
╠════╬══════════════╬═══════════════╬══════════════╬═══════════════╣
║ 1 ║ 1 ║ 2 ║ 2 ║ 1 ║ * duplicate
║ 1 ║ 1 ║ 2 ║ 2 ║ 3 ║
║ 2 ║ 1 ║ 3 ║ 3 ║ 2 ║
║ 3 ║ 2 ║ 1 ║ 1 ║ 2 ║ * duplicate
║ 3 ║ 2 ║ 1 ║ 1 ║ 3 ║
║ 4 ║ 2 ║ 3 ║ 3 ║ 2 ║ * duplicate
║ 5 ║ 3 ║ 2 ║ 2 ║ 1 ║
║ 5 ║ 3 ║ 2 ║ 2 ║ 3 ║ * duplicate
╚════╩══════════════╩═══════════════╩══════════════╩═══════════════╝
单击下面的链接以获取此查询的运行示例。
关于mysql - 在 MySQL 查找表中删除重复的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33141020/