从自联接中获取唯一对,以及没有匹配的行

时间:2015-04-02 04:38:27

标签: sql postgresql duplicates left-join

我遇到了避免查询重复行的问题,除了重复值在列之间交替。

我有:

select player_standings.player_ID, matched_player.player_ID 
from player_standings 
left join 
(select player_ID, wins from player_standings) as matched_player 
on matched_player.wins = player_standings.wins 
and matched_player.player_ID != player_standings.player_ID

player_standings的布局:

player_ID serial PRIMARY KEY,
wins int NOT NULL

说我在player_standings中有以下行:

player_id | wins
----------+-------
1253      | 1
1251      | 1
1252      | 0
1250      | 0
1259      | 7

我回来了:

1253, 1251
1252, 1250
1250, 1252  -- reverse dupe
1251, 1253  -- reverse dupe
1259, NULL

我想要的结果是:

1253, 1251
1252, 1250
1259, NULL

1 个答案:

答案 0 :(得分:4)

一种方式:

SELECT DISTINCT
       GREATEST (p1.player_id, p2.player_id) AS id1
     , LEAST    (p1.player_id, p2.player_id) AS id2
FROM   player_standings p1
LEFT   JOIN  player_standings p2 ON p1.wins = p2.wins
                                AND p1.player_id <> p2.player_id;

另一种方式:

SELECT p1.player_id AS id1, p2.player_id AS id2
FROM   player_standings p1
JOIN   player_standings p2 USING (wins)
WHERE  p1.player_id > p2.player_id;

UNION ALL
SELECT player_id AS id1, NULL::int AS id2
FROM   player_standings p
WHERE  NOT EXISTS (
   SELECT 1
   FROM   player_standings
   WHERE  wins = p.wins
   AND    player_id <> p.player_id
   );

表达式p1.player_id > p2.player_id排除了重复项(除非您在基表中有重复项)。

UNION ALL在没有匹配的情况下添加每一行。