2016-03-21 53 views
6

我一直在使用这个,所以现在是充分了解它的时候了。假设这样的查询:多个LEFT连接 - 什么是“左”表?

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? (或者它是一样的吗?)

+1

根据你如何加入数据(你的例子中的foo和bars),例如,如果在语句“... JOIN c ON bar ...”中,条件使用表a和b ,它将成为JOIN b ON foo。 –

+2

'(左连接b)左连接c',即第一个'a'是左表,然后'(左连接b)'是下一个左表。 – jarlh

+0

@ jarlh如果你把它写成答案并提供参考资料,我会接受它 – vektor

回答

3

一个FROM条款解析由左到右(除非用括号覆盖)的条件:

在最后一种情况,如果你写这样将是对可读性的改善。所以:

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

这在documentationFROM条款的join-type部分解释:

使用括号如果需要确定的顺序

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

如解析筑巢。在 没有括号,JOIN从左到右嵌套。在任何情况下,JOIN 比分隔FROM -list项目的逗号的绑定更紧密。

因此,一系列LEFT JOIN s保留了第一个提到的表中的所有记录。这是一个方便。

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

+0

我已经调整了您的示例中的缩进以更强调括号。如果你不同意这个看起来更好,请随时回复我的道歉。 :) – IMSoP

+0

@IMSoP。 。 。我非常强烈地反对它更好,但我不会改变它。 –

0

这里是多连接操作。 SQL是一种描述获取结果的语言,而不是如何获取它们。优化器将决定首先执行哪个连接,具体取决于它认为最有效的连接。 你可以阅读一些资料
https://community.oracle.com/thread/2428634?tstart=0
我认为,它适用于PostgreSQL的

+0

你能否提供一些参考? – vektor

+0

对不起,第一个错误的答案。 –

+0

@格莱斯。 。 。语义顺序(如何解释连接)与执行顺序(如何实现连接)无关。因此,你已经回答了一个不同的问题。 –

0

同样这可能是两个,这取决于你如何连接(在你的例子中,foo和酒吧)的数据。

例如,如果在你的例子中,你想加入一个与b和一个与c,T1将是一个。

但是,如果你的意图是加入一个b和与c的结果,那么T1将是一个左加入b ON foo。

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