MySQL成对查询
如何选择尚未与“alpha”配对的所有玩家?输出='伽马'。即使pairs表为空,它也应该工作MySQL成对查询,mysql,select,join,Mysql,Select,Join,如何选择尚未与“alpha”配对的所有玩家?输出='伽马'。即使pairs表为空,它也应该工作 table: players +----------+-------+ | playerID | name | +----------+-------+ | 1 | alpha | | 2 | beta | | 3 | gamma | +----------+-------+ table: pairs +---------+---------+ | pl
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”和“gamma”。在联接中,“beta”与“alpha”和“gamma”配对出现两次,每次一次。WHERE条件消除了一行“beta”。我想要的是消除所有“beta”行。我是新来的,尝试了各种组合的小组,有等,我无法让它工作
类似的东西应该适用于这种情况
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'
)
如果pairs表中的player1和player2列的位置发生变化,您可能必须在子查询中使用case。类似的内容应该适用于这种情况
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'
)
如果pairs表中的player1和player2列的位置发生变化,您可能必须在子查询中使用case。这应该可以做到:
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'
)
;
这应该做到:
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'
)
;
我会把它分解成小块,然后拼凑起来。首先获取alpha玩家的id:
SELECT playerID
FROM players
WHERE name = 'alpha';
下一步将是找出如何排除。我会得到所有与玩家1配对的玩家的列表。我通过选择player1为“alpha”的所有player2值和player2为“alpha”的所有player1值来实现这一点,如下所示:
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不是阿尔法,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);
这里有个例子。我会把它分解成更小的小块,然后拼凑起来。首先获取alpha玩家的id:
SELECT playerID
FROM players
WHERE name = 'alpha';
下一步将是找出如何排除。我会得到所有与玩家1配对的玩家的列表。我通过选择player1为“alpha”的所有player2值和player2为“alpha”的所有player1值来实现这一点,如下所示:
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不是阿尔法,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);
示例。替代解决方案,不使用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);
替代解决方案,不使用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);
确保结果不会返回Andy@Drew:留给学生做练习;。。。例如,您可以执行join而不是subselect,并将and player.id!=joined_table.id请确保结果不返回Andy@Drew:留给学生做练习;。。。例如,您可以执行join而不是subselect,并将and player.id!=joined_table.I你还在努力解决这个问题吗?没有。我更喜欢在编辑中使用我的解决方案,而不是答案,因为我不在编辑中使用NOT。但我真的很感激为下面的答案所做的努力。谢谢,伙计,它起作用了!您可以随时回答自己的问题并接受它,这可能对未来的读者更有用,因为他们会将您的编辑误认为是问题的一部分而不是解决方案。如果答案填补了一些空白,使您能够解决问题,至少你可以给他们一个投票,因为他们花时间和精力帮助你,结果却没有得到任何回报,因为你不喜欢他们的答案。同样,不要编辑你的帖子来包含答案。相反,将其作为答案发布。你也可以投票并引用任何有助于你解决问题的答案/评论。我已将帖子回滚以排除已编辑的答案。请随意将其作为实际答案发布。您仍在努力解决此问题吗?不。不知何故,我更喜欢在编辑中使用我的解决方案,而不是答案,因为我不在编辑中使用NOT。但我真的很感激为下面的答案所做的努力。谢谢,伙计,它起作用了!您可以随时回答自己的问题并接受它,这可能对未来的读者更有用,因为他们会将您的编辑误认为是问题的一部分而不是解决方案。如果答案填补了一些空白,使您能够解决问题,至少你可以给他们一个投票,因为他们花时间和精力帮助你,结果却没有得到任何回报,因为你不喜欢他们的答案。同样,不要编辑你的帖子来包含答案。相反,将其作为答案发布。你也可以投票并引用任何有助于你解决问题的答案/评论。我已将帖子回滚以排除已编辑的答案。如果一个新球员从来没有和任何人打过球,我想这个球员不会出现在结果集中,但应该出现在结果集中,那会发生什么呢?不过我还是很喜欢这种方法。我修改过的版本在所有情况下都有效,包括你提到的场景。如果一个新玩家从来没有玩过任何人,会发生什么?我想这个玩家不会出现在结果中
不是,但应该?不过,我确实喜欢这种方法。我修改过的版本在所有情况下都有效,包括您提到的场景。