使用多个联接而不使用子查询的SQL查询

使用多个联接而不使用子查询的SQL查询,sql,postgresql,Sql,Postgresql,假设我有三个包含这些列的表 Players - id, name Events - id, name Games - first_player_id, second_player_id, event_id. 我需要玩家在事件中进行的游戏的详细信息。 我可以写这样的查询 SELECT players.id, events.id as event_id, (SELECT name as player_one_name from players where i

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

      Players - id, name
      Events - id, name
      Games - first_player_id, second_player_id, event_id. 
我需要
玩家
事件
中进行的
游戏
的详细信息。 我可以写这样的查询

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;"
这里我使用两个子查询来获取玩家的名字并给出正确的结果。这个查询可以优化吗?例如,我可以删除任何
子查询
内部连接

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


谢谢。

如果您不想在select语句中使用子查询,则必须为每个子集提供联接。因为您的数据库是面向集合的,所以两个内部联接将被证明更有效

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

必须为每个外键执行联接

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

目前公认的答案是关于两次加入
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
    列表中的表后,在查询中只有该别名可见,而不是表的原始名称

非常感谢!将在30秒内接受您的回答:P:DMy的目标是让参加某个活动的玩家参加游戏。因此,如果事件中有玩家,并且游戏中有该事件,我只需要行。如果我加入左边,我也会得到没有玩家的游戏和事件,对吗?@BharathMg:没错。然后把
左键放下。