时间:2015-10-19 15:20:33

标签: mysql select join

如何选择尚未配对的所有播放器' alpha' ? (输出=' gamma')。即使对表为空,它也应该工作。

table: players
+----------+-------+
| playerID | name  |
+----------+-------+
|        1 | alpha |
|        2 | beta  |
|        3 | gamma |
+----------+-------+

table: pairs
+---------+---------+
| player1 | player2 |
+---------+---------+
|       2 |       3 |
|       1 |       2 |
+---------+---------+

我现在已经挣了几个小时。对于例如如果我这样做

SELECT p.*, r.*
FROM players p
JOIN pairs r
    ON (player1 = playerID) OR (player2 = playerID)
WHERE
    ((r.player1 != 1) AND (r.player2 != 1));

输出是' beta'和伽玛'。在加入中,' beta'出现两次(每次出现一次,用于配对' alpha' gamma')。并且WHERE条件消除了一行' beta'。我想要的是所有排的' beta'要被淘汰我是新手,并尝试过GROUP BY,HAVING等的各种组合。我无法让它发挥作用。

SQL Fiddle here.

4 个答案:

答案 0 :(得分:3)

我会把它分解成更小的位并将它拼凑在一起。首先获取alpha版玩家的ID:

SELECT playerID
FROM players
WHERE name = 'alpha';

下一步是弄清楚如何排除。我将获得与玩家1配对的所有玩家的列表。我通过选择所有player2值(其中player1为'alpha')和所有player1值(其中player2为'alpha')来完成此操作:

SELECT p.player2
FROM pairs p
JOIN(
  SELECT playerID
  FROM players
  WHERE name = 'alpha') b ON b.playerID = p.player1
UNION
SELECT p.player1
FROM pairs p
JOIN(
  SELECT playerID
  FROM players
  WHERE name = 'alpha') b ON b.playerID = p.player2;

一旦你完成了这个,剩下的唯一步骤就是从玩家身上拉出1)而不是alpha而2)不在上面的列表中:

SELECT *
FROM players
WHERE playerID NOT IN(
  SELECT playerID
  FROM players
  WHERE name = 'alpha') 
AND playerID NOT IN(
  SELECT p.player2
  FROM pairs p
  JOIN(
    SELECT playerID
    FROM players
    WHERE name = 'alpha') b ON b.playerID = p.player1
  UNION
  SELECT p.player1
  FROM pairs p
  JOIN(
    SELECT playerID
    FROM players
    WHERE name = 'alpha') b ON b.playerID = p.player2);

SQL Fiddle示例。

答案 1 :(得分:1)

这样的事情应该适用于这种情况。

SELECT
    pl.*
FROM 
    players as pl
WHERE 
    pl.playerID NOT IN 
    (
      SELECT 
          p.player2
      FROM
          pairs AS p
      INNER JOIN 
          players plr ON plr.playerID = p.player1
      WHERE 
          plr.name='alpha'

    )

如果成对表中的player1和player 2列更改位置,则可能必须在子查询中使用CASE。

答案 2 :(得分:1)

这应该这样做:

drop table pair;
drop table player;

create table player (
    id int,
    name varchar(32)
);

create table pair (
    id1 int,
    id2 int
);

insert into player values (1, 'Andy');
insert into player values (2, 'Bob');
insert into player values (3, 'Carl');
insert into player values (4, 'Dave');

insert into pair values (2, 3);
insert into pair values (1, 2);
insert into pair values (3, 1);

select * from player where id not in (
select
    if(pair.id1 = player.id, pair.id2, pair.id1) as other_player
from 
    pair
    join player on pair.id1 = player.id or pair.id2 = player.id
where
    player.name = 'Andy'
) 
;

答案 3 :(得分:0)

另一种解决方案,不使用“NOT IN”。

方法:(所有用户) - (所有现有对手)

即使(所有现有对手)都为空,这也有效。

SELECT p.* FROM players p
LEFT JOIN (
    SELECT CASE
            WHEN (player1 = 1) THEN player2
            WHEN (player2 = 1) THEN player1
        END AS opponentID
    FROM pairs) existingOpponents
ON (p.playerID = existingOpponents.opponentID)
WHERE (existingOpponents.opponentID IS NULL) AND 
    (p.playerID != 1);