多个LEFT JOIN - 什么是“左”表?

时间:2016-03-21 15:39:17

标签: sql postgresql join outer-join

我一直在使用它,所以现在是时候完全理解它了。假设一个这样的查询:

SELECT 
  *
FROM a
LEFT JOIN b ON foo...
LEFT JOIN c ON bar...

documentation告诉我们

  

T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON boolean_expression

     

LEFT OUTER JOIN

     

首先,执行内连接。然后,对于T1中不满足与T2中的任何行的连接条件的每一行,在T2的列中添加具有空值的连接行。因此,连接表在T1中每行至少有一行。

问题很简单:在这种情况下T1是什么?是a吗?或者是a LEFT JOIN b ON foo? (或者,它是一样的吗?)

3 个答案:

答案 0 :(得分:5)

FROM子句从左到右解析条件(除非被括号覆盖)。所以:

FROM a 
LEFT JOIN b
     ON foo... 
LEFT JOIN c
     ON bar...

被解析为:

FROM (
        a 
        LEFT JOIN b
           ON foo...
     ) 
LEFT JOIN c
     ON bar...

join-type条款的FROM部分下的documentation对此进行了解释:

  

如有必要,请使用括号来确定嵌套顺序。在里面   没有括号,JOIN的巢从左到右。无论如何JOIN   比分隔FROM - 列表项的逗号更紧密地绑定。

因此,一系列LEFT JOIN将所有记录保存在第一个提到的表中。这很方便。

请注意,无论连接类型如何,FROM子句的解析都是相同的。

答案 1 :(得分:0)

这是多个连接操作。 SQL是一种语言,您可以在其中描述要获取的结果,而不是如何获取结果。优化器将根据它认为最有效的方式决定首先执行哪个连接。 你可以在这里阅读一些信息 https://community.oracle.com/thread/2428634?tstart=0
我认为,它对PostgreSQL来说是一样的

答案 2 :(得分:0)

它可以是两者,取决于您加入数据的方式(示例中的foo和bar)。

例如,如果在您的示例中,您想要使用b和a来加入a,那么T1将是a。

但是,如果你打算用b加上a和c的结果,那么T1将是一个LEFT JOIN b ON foo。

在最后一种情况下,如果你这样写,那将是对可读性的改进:

(a LEFT JOIN b ON foo) LEFT JOIN c ON bar