我一直在岁使用它,所以现在是时候完全理解它了。假设一个这样的查询:
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
? (或者,它是一样的吗?)
答案 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