Левое внешнее объединение с помощью знака + в Oracle 11g

sql oracle11g

540887 просмотра

4 ответа

3076 Репутация автора

Кто-нибудь может сказать мне, являются ли ниже 2 запроса примером левого внешнего соединения или правого внешнего соединения?

Table Part:
Name         Null?       Type
PART_ID      NOT NULL    VARCHAR2(4)
SUPPLIER_ID              VARCHAR2(4)

PART_ID SUPPLIER_ID
P1      S1
P2      S2
P3  
P4  

Table Supplier:
Name            Null?     Type
SUPPLIER_ID NOT NULL      VARCHAR2(4)
SUPPLIER_NAME   NOT NULL  VARCHAR2(20)

SUPPLIER_ID  SUPPLIER_NAME
S1           Supplier#1
S2           Supplier#2
S3           Supplier#3

Выведите на экран все детали независимо от того, поставляет их поставщик или нет:

SELECT P.Part_Id, S.Supplier_Name
ОТ Часть P, Поставщик S
ГДЕ P.Supplier_Id = S.Supplier_Id (+)

SELECT P.Part_Id, S.Supplier_Name
ОТ Часть P, Поставщик S
ГДЕ S.Supplier_Id (+) = P.Supplier_Id
Автор: Mike Источник Размещён: 02.07.2011 07:50

Ответы (4)


8 плюса

65574 Репутация автора

Эти два запроса выполняются OUTER JOIN. Смотри ниже

Oracle рекомендует использовать синтаксис OUTER JOIN предложения FROM, а не оператор соединения Oracle. На запросы внешнего соединения, использующие оператор соединения Oracle (+), распространяются следующие правила и ограничения, которые не применяются к синтаксису OUTTER JOIN предложения FROM:

  • Вы не можете указать оператор (+) в блоке запроса, который также содержит синтаксис соединения предложения FROM.

  • Оператор (+) может появляться только в предложении WHERE или в контексте левой корреляции (при указании предложения TABLE) в предложении FROM и может применяться только к столбцу таблицы или представления.

  • Если A и B объединяются несколькими условиями соединения, то вы должны использовать оператор (+) во всех этих условиях. Если вы этого не сделаете, то Oracle Database вернет только строки, полученные в результате простого соединения, но без предупреждения или ошибки, сообщив вам, что у вас нет результатов внешнего соединения.

  • Оператор (+) не создает внешнее соединение, если вы указываете одну таблицу во внешнем запросе, а другую таблицу - во внутреннем запросе.

  • Вы не можете использовать оператор (+) для внешнего соединения таблицы с самим собой, хотя самостоятельные объединения допустимы. Например, следующее утверждение недопустимо:

    -- The following statement is not valid:
    SELECT employee_id, manager_id
       FROM employees
       WHERE employees.manager_id(+) = employees.employee_id;
    

    Тем не менее, допустимо следующее самостоятельное соединение:

    SELECT e1.employee_id, e1.manager_id, e2.employee_id
       FROM employees e1, employees e2
       WHERE e1.manager_id(+) = e2.employee_id
       ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
    
  • Оператор (+) может применяться только к столбцу, а не к произвольному выражению. Однако произвольное выражение может содержать один или несколько столбцов, помеченных оператором (+).

  • Условие WHERE, содержащее оператор (+), нельзя объединить с другим условием с помощью логического оператора OR.

  • Условие WHERE не может использовать условие сравнения IN для сравнения столбца, отмеченного оператором (+), с выражением.

Если предложение WHERE содержит условие, которое сравнивает столбец из таблицы B с константой, то к столбцу должен применяться оператор (+), чтобы Oracle возвращал строки из таблицы A, для которых он сгенерировал пустые значения для этого столбца. В противном случае Oracle возвращает только результаты простого объединения.

В запросе, который выполняет внешние объединения более двух пар таблиц, одна таблица может быть сгенерированной нулем только для одной другой таблицы. По этой причине вы не можете применить оператор (+) к столбцам B в условии соединения для A и B и в условии соединения для B и C. Обратитесь к SELECT для синтаксиса внешнего соединения.

Взято с http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries006.htm

Автор: Rahul Размещён: 02.07.2011 08:01

181 плюса

17474 Репутация автора

Решение

TableA LEFT OUTER JOIN TableBэквивалентно TableB RIGHT OUTER JOIN Table A.

В Oracle (+)обозначает «необязательную» таблицу в JOIN. Итак, в вашем первом запросе это P LEFT OUTER JOIN S. Во втором запросе это так S RIGHT OUTER JOIN P. Они функционально эквивалентны.

В терминологии RIGHT или LEFT указывают, какая сторона объединения всегда имеет запись, а другая сторона может быть нулевой. Так что в P LEFT OUTER JOIN S, Pвсегда будет запись, потому что она есть LEFT, но Sможет быть нулевой.

Посмотрите этот пример от java2s.com для дополнительного объяснения.


Чтобы уточнить, я полагаю, я говорю, что терминология не имеет значения, так как она используется только для визуализации. Важно то, что вы понимаете, как это работает.


ПРАВО против ЛЕВОГО

Я видел некоторую путаницу в том, что имеет значение при определении ПРАВО против ЛЕВЫХ в неявном синтаксисе соединения.

ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ

SELECT *
FROM A, B
WHERE A.column = B.column(+)

ПРАВО НАРУЖНОЕ СОЕДИНЕНИЕ

SELECT *
FROM A, B
WHERE B.column(+) = A.column

Все, что я сделал, это поменялся сторонами терминов в предложении WHERE, но они все еще функционально эквивалентны. (См. Выше в моем ответе для получения дополнительной информации об этом.) Расположение (+)определяет ПРАВО или ВЛЕВО. (В частности, если (+)справа, это (+)левое соединение . Если слева, то это правое соединение.)


Типы JOIN

Два стиля JOIN - это неявные соединения и явные соединения . Это разные стили написания JOIN, но они функционально эквивалентны.

Смотрите этот ТАК вопрос .

Неявные соединения просто перечисляют все таблицы вместе. Условия соединения указаны в предложении WHERE.

Неявное ПРИСОЕДИНЕНИЕ

SELECT *
FROM A, B
WHERE A.column = B.column(+)

Явные СОЕДИНЕНИЯ связывают условия соединения с включением определенной таблицы, а не в предложении WHERE.

Явное ПРИСОЕДИНЕНИЕ

SELECT *
FROM A
LEFT OUTER JOIN B ON A.column = B.column

Эти неявные СОЕДИНЕНИЯ могут быть более трудными для чтения и понимания, и у них также есть несколько ограничений, так как условия соединения смешаны в других условиях WHERE. Таким образом, неявные соединения обычно рекомендуются в пользу явного синтаксиса.

Автор: Wiseguy Размещён: 02.07.2011 08:02

-2 плюса

33 Репутация автора

В этой теме есть неверная информация. Я скопировал и вставил неверную информацию:

ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ

SELECT *
FROM A, B
WHERE A.column = B.column(+)

ПРАВО НАРУЖНОЕ СОЕДИНЕНИЕ

SELECT *
FROM A, B
WHERE B.column(+) = A.column

Выше НЕПРАВИЛЬНО !!!!! Оно задом наперед. Как я определил, что это неверно, из следующей книги:

Oracle OCP Введение в Oracle 9i: Руководство по экзамену SQL . Таблица 3-1 содержит хорошее резюме по этому вопросу. Я не мог понять, почему мой конвертированный SQL не работал должным образом, пока я не пошел в старую школу и заглянул в печатную книгу!

Вот краткое содержание этой книги, построчно скопированное:

Синтаксис внешнего соединения Oracle:

from tab_a a, tab_b b,                                       
where a.col_1 + = b.col_1                                     

Эквивалент ANSI / ISO:

from tab_a a left outer join  
tab_b b on a.col_1 = b.col_1

Обратите внимание, что это обратное тому, что опубликовано выше. Я полагаю, что в этой книге могут быть ошибки, однако я доверяю этой книге больше, чем тому, что есть в этой теме. Это руководство к экзамену для громкого крика ...

Автор: somedude Размещён: 25.09.2014 03:59

2 плюса

37 Репутация автора

Я видел некоторые противоречия в ответах выше, я только что попробовал следующее на Oracle 12c, и следующее правильно:

ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ

SELECT *
FROM A, B
WHERE A.column = B.column(+)

ПРАВО НАРУЖНОЕ СОЕДИНЕНИЕ

SELECT *
FROM A, B
WHERE B.column(+) = A.column
Автор: Charles Размещён: 12.10.2016 06:37
Вопросы из категории :
32x32