sql - 同一个表上的 2 个外部联接?

标签 sql oracle join

这是一个困扰我好几天的问题,我搜索并搜索但找不到任何令人信服的答案!

简单的问题,为什么在 SQL 中限制有 2 个外部联接,即使在使用不同列的同一个表上,请检查下面的查询以更好地理解。我也可以使用嵌套子查询或 ANSI 连接来克服它们,但是为什么它甚至首先使用 (+) 运算符受到限制!

在这个问题中,我指的是错误:

ORA-01417: a table may be outer joined to at most one other table



我想问的是为什么允许这样做:
select * from
a, b, c
where a.a1 = b.b1
and a.a2 = c.c1

以及为什么不允许这样做:
select * from
a, b, c
where a.a1(+) = b.b1
and a.a2(+) = c.c1

请不要管 ANSI 和嵌套子查询

最佳答案

Oracle 文档中描述了该限制:Outer Joins

Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator. Outer join queries that use the Oracle join operator (+) are subject to the following rules and restrictions, which do not apply to the FROM clause OUTER JOIN syntax:

...

In a query that performs outer joins of more than two pairs of tables, a single table can be the null-generated table for only one other table. For this reason, you cannot apply the (+) operator to columns of B in the join condition for A and B and the join condition for B and C. Refer to SELECT for the syntax for an outer join.


这基本上意味着(在 ANSI/ISO 语法中描述)您不能使用旧的 (+)在 ANSI/ISO 中完全有效的语法:
--- Query 1 ---
  a 
RIGHT JOIN b
  ON a.x = b.x
RIGHT JOIN c 
  ON a.y = c.y
或者:
--- Query 1b ---
  c 
LEFT JOIN 
    b LEFT JOIN a
        ON a.x = b.x 
  ON a.y = c.y
这只是旧 Oracle 语法的众多限制之一。

至于这种限制的原因,可能是实现细节或/和这种连接的歧义。虽然上面的两个连接是 100% 等价的,但以下不等价于上面两个:
--- Query 2 ---
  a 
RIGHT JOIN c 
  ON a.y = c.y 
RIGHT JOIN b
  ON a.x = b.x 
中的测试SQL-Fiddle . 所以问题来了。专有连接应该如何解释为查询 1 或 2?
FROM a, b, c 
WHERE a.y (+) = c.y 
  AND a.x (+) = b.x 

如果表出现在(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 (+)

关于sql - 同一个表上的 2 个外部联接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17117096/

相关文章:

c# - QueryOver - 向 Join 添加附加条件

sql - Postgres 中的左外连接不返回空值

Oracle sql Developer 中的 Java 字符串参数

sql - 插入随机字符串、数字。以及乘法的结果

mysql - PL/SQL 错误 - 精确获取返回的行数超过请求的行数

android - 方法 "join"和类 "DeepCollectionEquality"未定义

mysql - SQL 查询 FROM 变量表

SQL Server 连接表语句

sql - 返回带有文本变量的查询

mysql - 您可以使用触发器修改插入时的外键吗?