如何选择尚未配对的所有播放器' 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等的各种组合。我无法让它发挥作用。
答案 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);