在子查询 JOIN 中引用外部查询
Posted
技术标签:
【中文标题】在子查询 JOIN 中引用外部查询【英文标题】:Reference to outer query in subquery JOIN 【发布时间】:2012-08-02 14:01:01 【问题描述】:我在这里呼吁 mysql 勇士。我的问题是我需要在子查询的左外部联接中使用对外部查询表的引用。 我知道这是不可能的,但我不知道如何用外部查询中的典型连接替换子查询过滤。
我将举一个典型的例子来说明我的问题。
这是奥运会,我有几支球队(比如乒乓球队),其中有 1 到 N 名球员。 当所有球员都与对方球队的所有球员交手时,两支球队之间的比赛就结束了。 简而言之,我有 3 张桌子:
Team (id, country);
Player (id, team_id, name)
Game (id, playerA_id, playerB_id).
我想搜索所有没有或不是每场比赛都与对方球队的所有球员(显然不在我的球队中)发生争议的球员。 这是我的查询:
SELECT t.*, p.*
FROM player p
INNER JOIN team t ON t.id = p.team_id AND t.id != My_Team_ID
WHERE EXISTS (
-- If an opposing team's player has played no game => game.id is NULL
-- If he hasn't played against all of my teammates => there will be at least one row where game.id is NULL
SELECT *
FROM player
INNER JOIN team ON team.id = player.team_id AND team.id = My_Team_ID
LEFT OUTER JOIN game ON player.id IN (game.playerA_id, game.playerB_id) AND p.id IN (game.playerA_id, game.playerB_id)
WHERE game.id IS NULL
)
出于实用目的,我已经放了一个转储:http://pastebin.com/HW3L5ukz 我试图将 LEFT OUTER JOIN 的第二个条件放在子查询的 WHERE 中,但它没有返回正确的结果。
关于如何实现这一目标的任何想法? 提前致谢
【问题讨论】:
en.wikipedia.org/wiki/Correlated_subquery? 如果 Game 和 Game_Player 是单独的表,这会更容易。 @MarcB :我试过了,但它没有返回正确的结果;如果我通过将我的 p.id 替换为玩家的 id 来单独键入我的子查询,它可以工作,但是如果我将 « LEFT OUTER JOIN p.id IN (game.playerA_id, game.playerB_id) » 作为« WHERE p.id IN ( game.playerA_id, game.playerB_id) »,它没有。我做了一个测试,其中一个对手没有与所有人交手,而另一个对手有,在 LEFT OUTER JOIN 的条件下,我得到了我的球员 - 与 WHERE 的情况相反。 @MarcusAdams :这只是为了简化问题,制作 2 个单独的表格有什么意义?游戏只是一个链接表 如果 Game_Player 有 game_id 和 player_id 作为列,如果您想查找特定玩家所在的游戏,您可以在 Game_Player 中查询单个列,而不是在 Game 中查询两个列。 【参考方案1】:SELECT p1.*, p2.*
FROM player p1
JOIN team t1
ON t1.id = p1.team_id AND t1.id = My_Team_ID
LEFT JOIN player p2
ON p2.id != p1.id
JOIN team t2
ON t2.id = p2.team_id AND t2.id != My_Team_ID
LEFT JOIN game g1
ON (g1.playerA_id = p1.id OR g1.playerB_id = p1.id)
AND (g1.playerA_id = p2.id OR g1.playerB_id = p2.id)
WHERE g1.id IS NULL
如果我为 My_Team_ID 使用 1,我会得到以下结果,其中显示了剩余的匹配项:
id team_id name id team_id name
1 1 Laurent Dupuis 6 2 Alec Russell
2 1 Stéphane Leroy 6 2 Alec Russell
3 1 Julien le Guen 4 2 Mark Johnsson
3 1 Julien le Guen 6 2 Alec Russell
【讨论】:
谢谢马库斯,它就像一个魅力。实际上,我真正的查询要复杂一些,所以我跳得更加复杂。但是通过这个简单的例子和你的答案,它看起来很明显。以上是关于在子查询 JOIN 中引用外部查询的主要内容,如果未能解决你的问题,请参考以下文章