查找并删除可在两列之间交换值的重复条目

时间:2016-09-16 15:04:30

标签: sql postgresql

我有以下数据结构,其中包含节点之间的关系。 relationships表格中包含from_idto_id,可以交换这些值。

我需要查找并删除重复项,每行留下一行。

| id    | node_from_id  | node_to_id |
---------------------------------
| 1     |   100         |   200      |
| 2     |   200         |   100      |
| 3     |   200         |   300      |
| 4     |   300         |   200      |
| 5     |   200         |   300      |
| 6     |   300         |   400      |
| 7     |   500         |   400      |

删除重复项后,我希望以下内容保留在表格中

| id    | node_from_id  | node_to_id |
---------------------------------
| 1     |   100         |   200      |
| 3     |   200         |   300      |
| 6     |   300         |   400      |
| 7     |   500         |   400      |

我能够相对简单地返回匹配的所有行但是要删除它们我只想返回实际的重复项以允许其中一个密钥对行保留。

这是我当前返回所有匹配行的查询

SELECT *
FROM relationships AS rel1
WHERE EXISTS (SELECT *
    FROM relationships AS rel2
    WHERE
        rel1.id <> rel2.id
    AND
    (
        (
            rel1.from_id = rel2.from_id AND
            rel1.to_id = rel2.to_id 
        )
        OR
        (
            rel1.from_id = rel2.to_id AND
            rel1.to_id = rel2.from_id
        )
    )
)

我以为我可以使用窗口函数并仅选择row_number() > 1行,但我似乎无法在EXISTS子查询中使用它。

如果有帮助,我已经为relationships available as CSV制作了实际数据

2 个答案:

答案 0 :(得分:2)

我喜欢使用smth

select  min(id),
        least (node_from_id, node_to_id) node_from_id,
        greatest(node_from_id, node_to_id) node_to_id
from    relationships
group   by         
        least (node_from_id, node_to_id) ,
        greatest(node_from_id, node_to_id) 

答案 1 :(得分:0)

-- SELECT * -- to test  which rows will be deleted
DELETE      -- to actually delete     
FROM ztable zt
WHERE zt.node_from_id > zt.node_to_id
AND EXISTS(
        select *
        FROM ztable nx
        WHERE nx.node_from_id = zt.node_to_id
        AND nx.node_to_id = zt.node_from_id
        );