SQL查询使用多个JOINS而不进行子查询

时间:2014-05-25 18:08:20

标签: sql postgresql

假设我有三个包含这些列的表,

      Players - id, name
      Events - id, name
      Games - first_player_id, second_player_id, event_id. 

我需要players中正在game中播放的event个详细信息。 我可以编写像

这样的查询
SELECT players.id, events.id as event_id, 
(SELECT name as player_one_name from players where id = games.first_player_id), 
(SELECT name as player_two_name from players where id = games.second_player_id), 
games.id as game_id  
    FROM events 
    INNER JOIN games on events.id = games.event_id 
    INNER JOIN players on games.first_player_id = players.id;"

这里我使用两个子查询来获取玩家名称。 并且它提供了正确的结果。这个查询可以优化吗?例如,我可以删除任何subqueryinnerjoin吗?

仅供参考,我使用PostgreSQL数据库。

感谢。

3 个答案:

答案 0 :(得分:2)

如果您不想在select语句中使用子查询,则必须为每个子集提供连接。由于您的数据库是面向设置的,因此两个INNER JOINS将更有效率。

SELECT players.id, events.id as event_id,
     player_one_name=player_one.name,
     player_tow_name=player_two.name
FROM events 
INNER JOIN games on events.id = games.event_id 
INNER JOIN players player_one on games.first_player_id = player_one.id
INNER JOIN players player_two on games.second_player_id = player_two.id

答案 1 :(得分:1)

您必须为每个外键执行连接

SELECT players_a.id, events.id as event_id, 
players_a.name as player_one_name,
players_b.name as player_two_name,
games.id as game_id  
    FROM events 
    INNER JOIN games on events.id = games.event_id 
    INNER JOIN players players_a on games.first_player_id = players.id
    INNER JOIN players players_b on games.first_player_id = players.id

答案 2 :(得分:0)

目前接受的答案是关于加入players表两次,但大多数错误。这可行:

SELECT e.id AS event_id
      ,g.id AS game.id
      ,p1.name AS first_player
      ,p2.name AS second_player
FROM   events e
LEFT   JOIN games    g ON g.event_id = e.id 
LEFT   JOIN players p1 ON p1.id = g.first_player_id 
LEFT   JOIN players p2 ON p2.id = g.second_player_id;
  • 使用LEFT [OUTER] JOIN来涵盖事件没有游戏或游戏没有两个玩家的情况。
  • 使用表别名来简化语法。要同时加入同一个表,您还需要至少需要一个表别名 将别名附加到FROM列表中的表后,只有 别名在查询中可见,而不是表的原始名称。
  • Study the manual for details.