【问题标题】:How to find LEFT OUTER JOIN or RIGHT OUTER JOIN with ORACLE JOIN (+)如何使用 ORACLE JOIN (+) 查找 LEFT OUTER JOIN 或 RIGHT OUTER JOIN
【发布时间】:2015-02-13 11:33:26
【问题描述】:

我对使用 Oracle 连接 (+) 符号正确查找左外连接和右外连接感到困惑。检查this 与this。我觉得两者矛盾。我的理解是,第一个链接说如果(+)号在右手边,它将是右外连接。

而第二个链接,我的理解是完全错误的。

请举例说明如何正确查找左右外连接?

【问题讨论】:

  • 你为什么不试试?:)
  • @a_horse_with_no_name:如果他们不需要维护旧版 Oracle SQL,没有人会费心去寻找有关 (+) 的信息。
  • @a_horse_with_no_name 但是我的应用程序在 2015 年使用它。这就是我想了解的原因。否则我怎么知道呢。
  • 有例外。如果您想使用FAST REFRESH 创建实体化视图,您必须使用旧的 Oracle 符号,否则无法快速刷新。 Oracle 自己并不认为这是一个错误。我的 SR 上的回答是:这只是缺少文档!
  • @a_horse_with_no_name:此限制适用于任何连接,而不仅仅是外部连接。

标签: sql oracle left-join right-join


【解决方案1】:

请举例说明如何正确查找左右外连接

我将尝试展示 Oracle 外连接语法 和 ANSI/ISO 语法 之间的区别。

左外连接 -

SELECT e.last_name,
  d.department_name
FROM employees e,
  departments d
WHERE e.department_id = d.department_id(+);

SELECT e.last_name,
  d.department_name
FROM employees e
LEFT OUTER JOIN departments d
ON (e.department_id = d.department_id);

右外连接 -

SELECT e.last_name,
  d.department_name
FROM employees e,
  departments d
WHERE e.department_id(+) = d.department_id;

SELECT e.last_name,
  d.department_name
FROM employees e
RIGHT OUTER JOIN departments d
ON (e.department_id = d.department_id);

全外连接 -

在 11gR1 原生支持 hash full outerjoin 之前,Oracle 会在内部通过以下方式转换 FULL OUTER JOIN -

SELECT e.last_name,
  d.department_name
FROM employees e,
  departments d
WHERE e.department_id = d.department_id(+)
UNION ALL
SELECT NULL,
  d.department_name
FROM departments d
WHERE NOT EXISTS
  (SELECT 1 FROM employees e WHERE e.department_id = d.department_id
  );

SELECT e.last_name,
  d.department_name
FROM employees e
FULL OUTER JOIN departments d
ON (e.department_id = d.department_id);

看看this。

【讨论】:

  • 以Right Outer Join 为例。如果我只在 where 子句中交换列名的一侧,它将是 Left Outer Join。例如:WHERE d.department_id(+) = e.department_id。所以这意味着我们无法在(+) 符号旁边识别Left Outer Join 或Right Outer Join。我们可以吗?
【解决方案2】:

左外连接只是意味着您要返回连接左侧的所有表,以及右侧表中的所有匹配行。

在旧式 Oracle 语法中,这将是:where t1.col1 = t2.col1 (+) 在 ANSI 语法中,这将是:from t1 left outer join t2 on (t1.col1 = t2.col1)

右外连接意味着您要返回连接右侧的所有表,以及左侧表中的所有匹配行。

在旧式 Oracle 语法中,这将是:where t2.col1 (+) = t1.col1 在 ANSI 语法中,这将是:from t2 right outer join t1 on (t2.col1 = t1.col1)

您当然会发现,只需颠倒表的顺序,您就可以将右外连接变成左外连接。大多数外连接都是左连接,可能是因为更容易想到“我想要所有第一个表,以及来自另一个表的任何匹配行”,而不是相反。当然是 YMMV!


ETA 以下示例:

左外连接:

with t1 as (select 1 col1, 10 col2 from dual union all
            select 2 col1, 20 col2 from dual union all
            select 3 col1, 30 col2 from dual),
     t2 as (select 1 col1, 100 col2 from dual)
select t1.*, t2.*
from   t1, t2
where  t1.col1 = t2.col1 (+)
order by t1.col1;

      COL1       COL2     COL1_1     COL2_1
---------- ---------- ---------- ----------
         1         10          1        100
         2         20                      
         3         30   

with t1 as (select 1 col1, 10 col2 from dual union all
            select 2 col1, 20 col2 from dual union all
            select 3 col1, 30 col2 from dual),
     t2 as (select 1 col1, 100 col2 from dual)
select t1.*, t2.*
from t1 left outer join t2 on (t1.col1 = t2.col1)
order by t1.col1;

      COL1       COL2     COL1_1     COL2_1
---------- ---------- ---------- ----------
         1         10          1        100
         2         20                      
         3         30   

右外连接:

with t1 as (select 1 col1, 10 col2 from dual union all
            select 2 col1, 20 col2 from dual union all
            select 3 col1, 30 col2 from dual),
     t2 as (select 1 col1, 100 col2 from dual)
select t1.*, t2.*
from   t1, t2
where t2.col1 (+) = t1.col1
order by t1.col1;

      COL1       COL2     COL1_1     COL2_1
---------- ---------- ---------- ----------
         1         10          1        100
         2         20                      
         3         30   

with t1 as (select 1 col1, 10 col2 from dual union all
            select 2 col1, 20 col2 from dual union all
            select 3 col1, 30 col2 from dual),
     t2 as (select 1 col1, 100 col2 from dual)
select t1.*, t2.*
from t2 right outer join t1 on (t2.col1 = t1.col1)
order by t1.col1;

      COL1       COL2     COL1_1     COL2_1
---------- ---------- ---------- ----------
         1         10          1        100
         2         20                      
         3         30   

【讨论】:

  • 我可以在你的同一个例子中写 Right Outer Join 像 t1.col1(+) = t2.col1 ( FROM t1 RIGHT OUTER JOIN t2 ON t1.col1 = t2.col ) 吗?因为我很困惑,因为你改变了桌子的一侧。请参阅 Lalit Kumar 的回复。
  • 在我上面的场景中,t1 表是我想要从中检索所有行的表,而 t2 表是我只想要匹配行的表。这就是为什么我在两组示例之间交换表名的原因;它们实际上都是同一个查询。
猜你喜欢
  • 2013-03-10
  • 2014-01-07
  • 2013-05-02
  • 2012-02-27
  • 2014-08-10
  • 2015-01-10
  • 2019-09-03
  • 2020-01-10
  • 1970-01-01
相关资源
最近更新 更多