从自连接中获取唯一对,加上没有匹配的行
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
将没有匹配项的每一行添加一次。
我在避免查询重复行时遇到问题,除了重复值在列之间交替。
我有:
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
将没有匹配项的每一行添加一次。