Как найти LEFT OUTER JOIN или RIGHT OUTER JOIN с помощью ORACLE JOIN (+)

Меня смущает поиск левого внешнего соединения и правого внешнего соединения со знаком соединения Oracle (+). Проверьте это и это. Я чувствую, что оба противоречат друг другу. Насколько я понимаю, первая ссылка говорит, что если знак (+) находится справа, это будет правое внешнее соединение.

Принимая во внимание, что со второй ссылкой мое понимание совершенно неверно.

Пожалуйста, поясните, как правильно найти правое и левое внешнее соединение на примере?


person ever alian    schedule 13.02.2015    source источник
comment
Почему бы просто не попробовать? :)   -  person Nightmaresux    schedule 13.02.2015
comment
@a_horse_with_no_name: Никто не станет искать (+), если им не нужно поддерживать устаревший Oracle SQL.   -  person sampathsris    schedule 13.02.2015
comment
@a_horse_with_no_name Но мое приложение использует его в 2015 году. Вот почему я хочу понять. Иначе как я вообще об этом узнаю.   -  person ever alian    schedule 13.02.2015
comment
Есть исключения. Если вы хотите создать материализованное представление с помощью FAST REFRESH, вы должны использовать старый синтаксис Oracle, иначе быстрое обновление невозможно. Сами Oracle не считают это ошибкой. Ответ на мой SR был: Это просто отсутствие документации!   -  person Wernfried Domscheit    schedule 13.02.2015
comment
@Wernfried: Спасибо - хотя я никогда бы не ожидал, что mview с внешним соединением будет быстро обновляться в первую очередь ...   -  person a_horse_with_no_name    schedule 13.02.2015
comment
@a_horse_with_no_name: это ограничение применяется к любому соединению, а не только к внешнему.   -  person Wernfried Domscheit    schedule 13.02.2015


Ответы (2)


Пожалуйста, объясните, как правильно найти правое и левое внешнее соединение на примере.

Я попытаюсь показать разницу между синтаксисом внешнего соединения 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 Oracle внутренне преобразовывал ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ следующим образом:

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

Взгляните на это.

person Lalit Kumar B    schedule 13.02.2015
comment
Возьмем пример Right Outer Join. Если я поменяю стороны имен столбцов ТОЛЬКО в предложении where, это будет Left Outer Join. Например: WHERE d.department_id(+) = e.department_id. Значит, мы не можем идентифицировать Left Outer Join или Right Outer Join рядом со знаком (+). мы можем? - person ever alian; 26.02.2015

Левое внешнее соединение просто означает, что вы хотите вернуть всю таблицу в левой части соединения и любые совпадающие строки из таблицы справа.

В старом синтаксисе 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   
person Boneist    schedule 13.02.2015
comment
Могу ли я написать Right Outer Join как t1.col1(+) = t2.col1 ( FROM t1 RIGHT OUTER JOIN t2 ON t1.col1 = t2.col ) в том же примере? потому что я смущен, так как вы меняете сторону стола. См. ответ Лалита Кумара. - person ever alian; 18.02.2015
comment
В моем вышеприведенном сценарии таблица t1 была таблицей, из которой я хотел получить все строки, а таблица t2 была той, из которой мне нужны были только совпадающие строки. Вот почему я поменял местами имена таблиц между двумя наборами примеров; все они фактически являются одним и тем же запросом. - person Boneist; 18.02.2015