1

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

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

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

4

2 回答 2

2

Please clarify how to find the right and left outer join properly with an example

I will give a try to show the difference between Oracle outer join syntax and the ANSI/ISO Syntax.

LEFT OUTER JOIN -

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);

RIGHT OUTER JOIN -

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);

FULL OUTER JOIN -

Before the native support of hash full outerjoin in 11gR1, Oracle would internally convert the FULL OUTER JOIN the following way -

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);

Have a look at this.

于 2015-02-13T12:03:05.740 回答
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   
于 2015-02-13T11:49:29.253 回答