排除非排他性的价值对

sne*_*son 5 sql oracle

使用英语很难描述这个问题,所以我将给出一些例子.

我有一张名为Games的桌子.每个游戏由游戏编号和玩家组成,分为两列:GameNum,PlayerNum.

我的问题是,我想选择那些参加过比赛的球员,而不是其他人.

以下是一些示例数据:

GameNum PlayerNum
1       100
1       101
2       102
2       103
3       102
3       104
4       105
4       106
5       106
5       107
6       100
6       101
Run Code Online (Sandbox Code Playgroud)

我想找回结果:

PlayerNum1 PlayerNum2
100        101
Run Code Online (Sandbox Code Playgroud)

这是因为我们可以看到玩家100和101是唯一一个彼此玩游戏的玩家,而没有其他玩家.102也玩了104,所以我们排除102和104.虽然105只玩了106的游戏,106也玩了107游戏,所以我们排除玩家105和106(因此107)的结果.这让我们只有玩家100和101.

每个GameNum只会在表格中出现两次(即每个游戏总是会有两个玩家).另请注意,我们并不关心玩家是否一起玩过多个游戏(例如GameNum 1和6) - 前提是他们只是互相玩过这些游戏.

我尝试使用min/max进行类似下面的查询,但我无法弄清楚如何排除与其他玩家玩过游戏的玩家.

SELECT *
FROM
(
    SELECT AU1.PlayerNum AS PlayerNum1, AU2.PlayerNum AS PlayerNum2
    FROM
    (
      SELECT GameNum, MIN(PlayerNum) AS PlayerNum
      FROM GAMES
      GROUP BY GameNum
      HAVING count(GameNum) = 2
    ) AU1
    INNER JOIN 
    (
      SELECT GameNum, MAX(PlayerNum) AS PlayerNum
      FROM GAMES
      GROUP BY GameNum
      HAVING count(GameNum) = 2
    ) AU2
    ON AU2.GameNum = AU1.GameNum
) T2
GROUP BY T2.PlayerNum1, T2.PlayerNum2
ORDER BY T2.PlayerNum1, T2.PlayerNum2;
Run Code Online (Sandbox Code Playgroud)

非常感谢!:)

编辑:这是使用上述数据创建表的基本版本的查询:

CREATE TABLE Games
(
    GameNum int,
    PlayerNum int
);

INSERT INTO Games (GameNum, PlayerNum) VALUES (1, 100);
INSERT INTO Games (GameNum, PlayerNum) VALUES (1, 101);
INSERT INTO Games (GameNum, PlayerNum) VALUES (2, 102);
INSERT INTO Games (GameNum, PlayerNum) VALUES (2, 103);
INSERT INTO Games (GameNum, PlayerNum) VALUES (3, 102);
INSERT INTO Games (GameNum, PlayerNum) VALUES (3, 104);
INSERT INTO Games (GameNum, PlayerNum) VALUES (4, 105);
INSERT INTO Games (GameNum, PlayerNum) VALUES (4, 106);
INSERT INTO Games (GameNum, PlayerNum) VALUES (5, 106);
INSERT INTO Games (GameNum, PlayerNum) VALUES (5, 107);
INSERT INTO Games (GameNum, PlayerNum) VALUES (6, 100);
INSERT INTO Games (GameNum, PlayerNum) VALUES (6, 101);
INSERT INTO Games (GameNum, PlayerNum) VALUES (5, 107);
INSERT INTO Games (GameNum, PlayerNum) VALUES (6, 100);
INSERT INTO Games (GameNum, PlayerNum) VALUES (6, 101);
Run Code Online (Sandbox Code Playgroud)

Iły*_*sov 2

尝试这样的事情(mysql语法):

select distinct least(t1.p1, t2.p2), greatest(t1.p1, t2.p2)
from
(
 select p1, max(p2) as p2
 from (select min(PlayerNum) as p1, max(PlayerNum) as p2 from GAMES group by GameNum union select max(PlayerNum) as p1, min(PlayerNum) as p2 from GAMES group by GameNum) as q1
 group by q1.p1
 having count(distinct p2)=1
) as t1
,
(
 select min(p1) as p1, p2
 from (select min(PlayerNum) as p1, max(PlayerNum) as p2 from GAMES group by GameNum union select max(PlayerNum) as p1, min(PlayerNum) as p2 from GAMES group by GameNum) as q2
 group by q2.p2
 having count(distinct p1)=1
) as t2
where t1.p1=t2.p1 and t1.p2=t2.p2
Run Code Online (Sandbox Code Playgroud)

http://sqlfiddle.com/#!2/4d9c4/9

大意:

  • 选择仅与另外 1 名玩家一起玩过的所有玩家 1
  • 选择仅与另一名玩家玩过游戏的所有玩家 2

加入两组以找出只与对方一起玩的玩家