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;