多个 LEFT JOIN - 什么是 "left" table?

Multiple LEFT JOINs - what is the "left" table?

我已经使用它 ,所以是时候全面了解它了。假设这样的查询:

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

First, an inner join is performed. Then, for each row in T1 that does not satisfy the join condition with any row in T2, a joined row is added with null values in columns of T2. Thus, the joined table always has at least one row for each row in T1.

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

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

一样有效

可能两者兼而有之,具体取决于您连接数据的方式(示例中的 foo 和 bars)。

例如,如果在您的示例中,您想将 a 与 b 和 a 与 c 连接,则 T1 将为 a。

但是,如果您的目的是将 a 与 b 连接,并将其结果与 c 连接,则 T1 将是 LEFT JOIN b ON foo。

在最后一种情况下,如果你这样写会提高可读性:

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

A 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...

这在 FROM 子句的 join-type 部分下的 documentation 中有解释:

Use parentheses if necessary to determine the order of nesting. In the absence of parentheses, JOINs nest left-to-right. In any case JOIN binds more tightly than the commas separating FROM-list items.

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

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