1

我在使用 PHP 查询的 mySQL 数据库中有三个表:

球员

player_id | player_name
-----------------------
1           Tom
2           Dick
3           Harry

游戏

game_id | game_name
-------------------
1         Tennis
2         Cricket
3         Rugby

gamePlayerRel

game_id | player_id
-------------------
1         2
1         3
2         3
3         2
3         3

我想要一个查询,它将返回玩家 ID 和姓名以及他们玩的游戏。如果他们不玩游戏——就像 Tom (1) 的情况——那么我想要 id 和 name 以及 a nullor0值。

期望的结果

player_id | player_name | game_id | game_name
---------------------------------------------
1           Tom           null      null
2           Dick          1         Tennis
2           Dick          3         Rugby
3           Harry         1         Tennis
3           Harry         2         Cricket
3           Harry         3         Rugby

我能得到的最接近的是以下查询:

SELECT players.player_id, players.player_name, gamePlayerRel.game_id, games.game_name
FROM players
INNER JOIN gamePlayerRel
INNER JOIN games
ON players.player_id = gamePlayerRel.player_id
AND gamePlayerRel.game_id=games.game_id

这很接近,只是它不返回分配给他们游戏的玩家的数据。在上面的例子中,结果是我想要的,除了 Tom (1) 和他的null值被排除在外。

我是这方面的超级菜鸟,所以如果我从错误的角度来看它,请说出来,如果你能提出一个查询,它会做我想做的事。

提前感谢您的任何帮助和建议。

4

3 回答 3

5

要返回您所展示的结果集,您实际上需要执行两个外部连接

SELECT players.player_id, players.player_name, gamePlayerRel.game_id, games.game_name
FROM players
    LEFT OUTER JOIN gamePlayerRel ON players.player_id = gamePlayerRel.player_id
    LEFT OUTER JOIN games ON gamePlayerRel.game_id=games.game_id

在您的情况下,这应该可以正常工作,但是,我真正认为您正在尝试做的是游戏和 gamePlayerRel 之间的内部联接,然后是该虚拟表和玩家表之间的左外部联接。您可以通过以下方式完成此操作:

SELECT players.player_id, players.player_name, playerGames.game_id,      playerGames.game_name
FROM players
    LEFT OUTER JOIN (Select gameplayerRel.player_id, games.game_id, games.game_name  from games inner join gamePlayerRel on games.game_id = gamePlayerRel.game_id) playerGames
       on players.player_id = playerGames.player_id

在您的情况下,您永远不需要这种替代语法,但有时事情会变得一团糟,因为两个左外连接方式在逻辑上并不完全等效。

这是一个显示查询结果的SQL Fiddle

我知道您使用的是 mysql,但这篇文章很好地解释了连接的细微差别,但它是为 MSSQL 编写的,尽管它应该同样适用于您。 http://weblogs.sqlteam.com/jeffs/archive/2007/10/11/mixing-inner-outer-joins-sql.aspx

于 2013-04-17T17:39:00.847 回答
3

这应该可以解决问题

SELECT players.player_id, players.player_name, gamePlayerRel.game_id, games.game_name
FROM players
    INNER JOIN gamePlayerRel ON players.player_id = gamePlayerRel.player_id
    LEFT OUTER JOIN games ON gamePlayerRel.game_id=games.game_id

您需要单独加入每张桌子,还需要LEFT OUTER JOIN为您的游戏桌使用 a。这将为 player/gamePlayerRel 表中的每场比赛至少引入一条记录。如果没有匹配,您将返回一个NULL值。

于 2013-04-17T16:42:23.617 回答
0

在 SO 的乐于助人的人向正确的方向轻推之后,我得到了一个查询,尽管我仍然不能 100% 确定它为什么会起作用。

SELECT players.player_id, players.player_name, gamePlayerRel.game_id, games.game_name
FROM players
INNER JOIN gamePlayerRel ON players.player_id = gamePlayerRel.player_id
LEFT OUTER JOIN games ON gamePlayerRel.game_id=games.game_id

感谢那些评论的人。这个网站再次证明了我所发现的最有用的网站之一:)

于 2013-04-18T10:27:50.297 回答