从自连接中获取唯一对,加上没有匹配的行

Get unique pairs from self-join, plus rows without a match

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

我有:

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

布局 table 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

一种方式:

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 排除重复项(除非你在基础 table 中有重复项)。

UNION ALL 将没有匹配项的每一行添加一次。