如何使用ORACLE JOIN(+)查找LEFT OUTER JOIN或RIGHT OUTER JOIN

时间:2015-02-13 11:33:27

标签: sql oracle left-join right-join

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

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

请详细说明如何通过示例正确找到右外连接和左外连接?

2 个答案:

答案 0 :(得分: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   

答案 1 :(得分:2)

  

请说明如何使用示例

正确找到右外连接和左外连接

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

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 -

在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