Oracle SQL中这两个左连接之间有区别吗?为什么

Oracle SQL中这两个左连接之间有区别吗?为什么,sql,oracle,left-join,Sql,Oracle,Left Join,及 不,它们是不同的-第一个查询中对TAB3的内部连接(在对TAB2的左连接之后)有效地将左连接转换回内部连接 第二个查询中的括号确保对TAB3的内部联接在左联接之前进行求值,因此它仍然是对TAB2的左联接,只返回那些有相应TAB3记录的TAB2记录(否则,TAB1记录将返回相应的空值)。您可能需要的是: SELECT * FROM TAB1 LEFT JOIN (SELECT * FROM TAB2 JOIN TAB3 ON TAB3.ID = TA


不,它们是不同的-第一个查询中对TAB3的内部连接(在对TAB2的左连接之后)有效地将左连接转换回内部连接


第二个查询中的括号确保对TAB3的内部联接在左联接之前进行求值,因此它仍然是对TAB2的左联接,只返回那些有相应TAB3记录的TAB2记录(否则,TAB1记录将返回相应的空值)。

您可能需要的是:

SELECT *
FROM TAB1
LEFT JOIN (SELECT *
           FROM TAB2
           JOIN TAB3 ON TAB3.ID = TAB2.ID_TAB3) T
ON T.ID_TAB1 = TAB1.ID;
在第一个查询中,在拥有
左JOIN
并将其关联到
ON
子句之后,下一个
JOIN
(任何类型)将针对整个构造的潜在结果集(即已加入的
TAB2
TAB1
)。下一个连接是
内部连接
,必须完全满足该连接才能完成

然而,在上面的查询中,我引入了一个
左连接
,但在我在左连接的“右侧”完成进一步的连接之前,不要在子句上引入它的关联


只需下载、安装Oracle Express即可。此脚本:

SELECT * 
FROM TAB1 
LEFT JOIN TAB2
JOIN TAB3
 ON TAB3.ID = TAB2.ID_TAB3
 ON TAB2.ID_TAB1 = TAB1.ID; 
工作,并按预期运行


如果您认为
JOIN
引入了左括号
,以及
上的
引入了右括号
,那么您可能更容易思考此查询的作用。然后,
JOIN
s和
ON
以通常匹配括号的方式进行匹配

或另一种相等的方式是考虑每个联接子句是“打开”的,直到遇到对应的<代码> < /COD>。但是将

上的
连接匹配的规则是找到最近的“打开的”
连接


无论如何,在上面的查询中,ON
子句的第一个
满足
TAB2
TAB3
之间的连接。第二个
ON
子句满足
TAB1
和连接(
TAB2
TAB3
)之间的
LEFT JOIN

这不是副作用吗?当我写LEFT时,我希望该表及其所有连接都有一个LEFT连接。好吧,你可以随时写信给Oracle(以及其他DB提供程序和ANSI),告诉他们他们做错了……为什么他们要将LEFT转换为内部连接?@CosminVacaroiu:他们什么都不转换。您的第二个条件(在
JOIN
上)使其有效地成为
内部联接
@CosminVacaroiu:换句话说:在第一个查询中,您首先离开了JOIN TAB1到TAB2;然后,通过将这两个表连接在一起生成的数据集本身根据TAB2中的字段内部连接到TAB3。由于这些字段在TAB2记录不存在的情况下将为空,因此您将尝试在条件
TAB3.ID=NULL
下对TAB3进行内部联接,该条件的计算结果永远不会为真。我不知道,但如果不启用join,或不启用2,则无法进行join。我明白您的意思。编辑。这是有效的ANSI语法。@Damien:很抱歉(错误的)更新。我认为它需要括号才能工作。@CosminVacaroiu-好吧,我将浪费20分钟的时间下载并安装Oracle Express。我已经添加了为测试运行的脚本。所以,没有语法错误。@ypercube-Nope,只是下载并测试了Oracle express。括号可能更容易阅读,但没有括号是正确的。
SELECT * 
FROM TAB1 
LEFT JOIN TAB2
JOIN TAB3
 ON TAB3.ID = TAB2.ID_TAB3
 ON TAB2.ID_TAB1 = TAB1.ID; 
CREATE TABLE TAB1 (
    ID int not null
);
CREATE TABLE TAB2 (
    ID_TAB1 int not null,
    ID_TAB3 int not null
);
CREATE TABLE TAB3 (
    ID int not null
);
INSERT INTO TAB1 (ID) VALUES (1);
INSERT INTO TAB1 (ID) VALUES (2);
INSERT INTO TAB3 (ID) VALUES (1);
INSERT INTO TAB3 (ID) VALUES (2);
INSERT INTO TAB2 (ID_TAB1,ID_TAB3) VALUES (2,2);
SELECT * 
FROM TAB1 
LEFT JOIN TAB2
JOIN TAB3
 ON TAB3.ID = TAB2.ID_TAB3
 ON TAB2.ID_TAB1 = TAB1.ID;