这是一个令我难以置信几天的问题,我搜索和搜索但找不到任何令人信服的答案!
简单的问题,为什么限制在SQL中有2个外部联接,即使使用不同的列也在同一个表上,检查下面的查询以便更好地理解.我也可以使用嵌套的子查询或ANSI连接来克服它们,但是为什么它甚至首先使用(+)运算符进行限制!
在这个问题中,我指的是错误:
ORA-01417:一个表可以外部连接到至多另一个表
我想问的是为什么允许这样做:
select * from
a, b, c
where a.a1 = b.b1
and a.a2 = c.c1
Run Code Online (Sandbox Code Playgroud)
为什么不允许这样做:
select * from
a, b, c
where a.a1(+) = b.b1
and a.a2(+) = c.c1
Run Code Online (Sandbox Code Playgroud)
请单独保留ANSI和嵌套子查询
ype*_*eᵀᴹ 10
Oracle文档中描述了该限制:外部联接
Oracle建议您使用FROM子句OUTER JOIN语法而不是Oracle join运算符.使用Oracle连接运算符(+)的外连接查询受以下规则和限制的约束,这些规则和限制不适用于FROM子句OUTER JOIN语法:
...
在执行两个以上表对的外连接的查询中,单个表可以是仅针对另一个表的空生成表.因此,在A和B的连接条件以及B和C的连接条件中,不能将(+)运算符应用于B的列.有关外连接的语法,请参阅SELECT.
这基本上意味着(在ANSI/ISO语法中描述)你不能使用旧(+)语法在ANSI/ISO中完全有效:
--- Query 1 ---
a
RIGHT JOIN b
ON a.x = b.x
RIGHT JOIN c
ON a.y = c.y
Run Code Online (Sandbox Code Playgroud)
要么:
--- Query 1b ---
c
LEFT JOIN
b LEFT JOIN a
ON a.x = b.x
ON a.y = c.y
Run Code Online (Sandbox Code Playgroud)
这只是旧Oracle语法的许多限制之一.
至于这种限制的原因,可能是实现细节或/和这种连接的模糊性.虽然上面的两个连接是100%等效,但以下不等同于以上两个:
--- Query 2 ---
a
RIGHT JOIN c
ON a.y = c.y
RIGHT JOIN b
ON a.x = b.x
Run Code Online (Sandbox Code Playgroud)
请参阅SQL-Fiddle中的测试.所以问题出现了.应该如何解释专有连接,如查询1或2?
FROM a, b, c
WHERE a.y (+) = c.y
AND a.x (+) = b.x
Run Code Online (Sandbox Code Playgroud)
如果一个表出现在(2个或更多)外连接的左侧,则没有限制.即使使用旧语法,这些也是完全有效的:
FROM a
LEFT JOIN b ON a.x = b.x
LEFT JOIN c ON a.y = c.y
...
LEFT JOIN z ON a.q = z.q
FROM a, b, ..., z
WHERE a.x = b.x (+)
AND a.y = c.y (+)
...
AND a.q = z.q (+)
Run Code Online (Sandbox Code Playgroud)