SQL - 将2个外键连接到1个主键

时间:2009-08-30 21:35:55

标签: sql mysql

我有两个表,游戏和团队。我的sql语句应该如何制作一个链接到TeamID1和TeamID2字段的TeamName的游戏列表?我相信我可以使用左连接,但我不知道如何处理链接到一个主键的两个外键。非常感谢您提供的任何帮助。

游戏

游戏ID
TeamID1
TeamID2
结果

TeamID
TeamName

5 个答案:

答案 0 :(得分:15)

我经常看到人们在同一个查询中加入一个表或多次加入表的想法(就像在这里一样)。一旦掌握,对于在行之间有很多关系的表(例如必须互相玩的团队列表!),这是一种很好的技术。正如其他人指出的那样,您需要使用两个inner join来完成此任务:

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
    ...

这样,可以恰当地命名列,而不是让t1t2列共享相同的名称。

现在,解决关于left join是什么的混淆。你看,left join将从第一个(或左)表中获取所有行,然后将连接条件中的任何行与第二个(或右)表匹配。对于左表中的任何行,您将在null表的所有列中获得right

深入研究一个例子,让我们说某人因为某种原因在其中一行上为nullTeamID2。我们还要说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不存在,我们将获得null个。它看起来像这样:

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上),同时允许您从表中获取数据以进行内部比较。这在尝试查找某些内容或相关行的顺序时非常有用。

无论如何,我希望这个非常漫无边际的答案可以帮助某个人。

答案 1 :(得分:4)

SELECT *
FROM Games G
INNER JOIN Teams T1
   ON G.TeamID1 = T1.TeamID
INNER JOIN Teams T2
   ON G.TeamID2 = T2.TeamID

答案 2 :(得分:2)

我不认为你需要左外连接,除非游戏中的两支球队中的一支是可选的。从逻辑上讲,似乎两者都是必需的,因此您的查询将如下所示:

SELECT *
FROM Games AS G
INNER JOIN Teams AS T1 ON T1.TeamID = G.TeamID1
INNER JOIN Teams AS T2 ON T2.TeamID = G.TeamID2

答案 3 :(得分:1)

如果TeamID1和TeamID2不是NULL,那么你想使用INNER JOIN,否则你可以使用LEFT JOIN。

答案 4 :(得分:0)

您需要使用别名:

SELECT GameID, team1.TeamName, team2.TeamName
FROM Games INNER JOIN teams team1 ON (Games.TeamID1 = team1.TeamID)
           INNER JOIN teams team2 ON (Games.TeamID2 = team2.TeamID)