根据 http://www.orafaq.com/node/855 该表中"不完整加入线"的记录
错误的编码方式是:
select *
from T1, T2, T3, T4
where T1.C1 = T2.C1(+)
and T2.C2 = T3.C2(+)
and T3.C3 = T4.C3;
Run Code Online (Sandbox Code Playgroud)
正确的编码方式是:
select *
from T1, T2, T3, T4
where T1.C1 = T2.C1(+)
and T2.C2 = T3.C2(+)
and T3.C3 = T4.C3(+);
Run Code Online (Sandbox Code Playgroud)
我无法理解.我可能想要在其他表之间进行等连接T3和T4以及外连接.为什么作者说它不正确?
根据http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5229892958977,
Tom在他的回答中使用了以下示例,该示例与上面列出的"Incomplete Join Trail"示例类似,
select *
from t1,t2,t3
where t1.x = t2.x and t2.y = t3.y(+);
Run Code Online (Sandbox Code Playgroud)
谁能帮我理解这个?
编辑:
如果我错了,请纠正我.根据Allan的回答,以下代码是正确的:
select *
from T1, T2, T3, T4
where T3.C3 = T4.C3
and T1.C1 = T2.C1(+)
and T2.C2 = T3.C2(+);
Run Code Online (Sandbox Code Playgroud)
如果以上是正确的,它是否等同于以下引用的答案?[即,我们可以在oracle的sql中使用引用的答案中没有子查询吗?]
SELECT *
FROM t1, t2, (SELECT *
FROM t3, t4
WHERE t3.c3 = t4.c3) t3_4
WHERE t1.c1 = t2.c1(+) AND t2.c2 = t3_4.c2(+);
Run Code Online (Sandbox Code Playgroud)
内部联接需要存在匹配的行才能返回行.在第一个查询中,行T1必须存在于表T1和T4中,以便返回结果行.由于T1通过经过T2和T3连接到T4,因此这些外连接呈现无关紧要.您可以非常轻松地检查这一点,因为优化器会知道它们是无关紧要的,并会在解释计划中将它们显示为内连接.
您仍然可以在T3和T4之间建立内部联接,但是您需要在子查询中执行此操作以使外部联接具有T2功能:
SELECT *
FROM t1, t2, (SELECT *
FROM t3, t4
WHERE t3.c3 = t4.c3) t3_4
WHERE t1.c1 = t2.c1(+) AND t2.c2 = t3_4.c2(+);
Run Code Online (Sandbox Code Playgroud)
顺便提一下,SQL-99语法最近是首选,这将允许您在没有子查询的情况下执行此操作:
SELECT *
FROM t1
LEFT JOIN t2
ON t1.c1 = t2.c1
LEFT JOIN (t3
JOIN t4
ON t3.c3 = t4.c3)
ON t2.c2 = t3.c2;
Run Code Online (Sandbox Code Playgroud)
最后,在您使用AskTom的示例中,外连接位于链中的最后一个连接,而不是中间连接.那个案子没问题.
关于修订后的问题,新查询不起作用.该where子句未被排序,因此优化器将以与原始查询完全相同的方式处理该子句.据我所知,除了在from条款中使用某种形式的子条款外,没有办法解决这个问题.
| 归档时间: |
|
| 查看次数: |
14123 次 |
| 最近记录: |