我经常看到人们对将一个表连接到自身或在同一个查询中多次连接(就像这里一样)的想法而苦苦挣扎。一旦掌握,它是一种很好的技术,可以用于行之间有很多关系的表格(例如必须互相比赛的团队列表!)。正如其他人指出的那样,您需要使用两个inner joins 来完成此操作:
select
*
from
games g
inner join teams t1 on
g.teamid1 = t1.teamid
inner join teams t2 on
g.teamid2 = t2.teamid
所以,如果您的 games 表如下所示:
GameID TeamID1 TeamID2
----------------------------
1 1 3
2 4 2
3 2 1
你会得到以下结果集:
g.GameID g.TeamID1 g.TeamID2 t1.TeamID t1.Name t2.TeamID t2.Name
----------------------------------------------------------------------------------
1 1 3 1 Lions 3 Bears
2 4 2 4 Oh My 2 Tigers
3 2 1 2 Tigers 1 Lions
当然,如果我是我,为了可用性,我会在 select 语句中为这些列加上别名:
select
g.GameID,
t1.Name as Team1,
t2.Name as Team2
from
...
这样,可以适当地命名列,而不是让t1 和t2 列共享相同的名称。
现在,解决关于 left join 是什么的困惑。您会看到,left join 将从第一个(或左)表中获取所有行,然后将连接条件中的任何行与第二个(或右)表匹配。对于左表中的任何行,您将在 right 表的所有列中获得 null。
深入研究一个示例,假设有人出于某种原因在其中一行中为TeamID2 输入了null。我们也假设一个由TeamID 4 组成的团队曾经存在,但现在已经不存在了。
GameID TeamID1 TeamID2
----------------------------
1 1 3
2 4 2
3 1 null
现在,让我们看一下left join 在查询中的含义:
select
*
from
games g
left join teams t1 on
g.teamid1 = t1.teamid
left join teams t2 on
g.teamid2 = t2.teamid
从逻辑上讲,这将获取我们所有的games,然后将它们与各自的teams 匹配。但是,如果TeamID 不存在,我们将得到nulls。它看起来像这样:
g.GameID g.TeamID1 g.TeamID2 t1.TeamID t1.Name t2.TeamID t2.Name
----------------------------------------------------------------------------------
1 1 3 1 Lions 3 Bears
2 4 2 null null 2 Tigers
3 1 null 1 Lions null null
因此,left join仅在团队是可选的情况下是必需的。
在您的情况下,您将使用inner join 多次加入一个表。这是一种非常常见的做法,而且非常有用。它避免了子查询的一些陷阱(尤其是在 MySQL 上),同时允许您从表中获取数据以进行表内比较。这在尝试查找某事物或相关行的顺序时非常有用。
无论如何,我希望这个非常漫无边际的答案可以帮助某个地方的人。