Left Outer Join с использованием знака + в Oracle 11g
Может ли кто-нибудь сказать мне, есть ли ниже 2 запроса - пример Left Outer Join или Right Outer Join?
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
FROM Part P, Supplier S
WHERE P.Supplier_Id = S.Supplier_Id (+)
SELECT P.Part_Id, S.Supplier_Name
FROM Part P, Supplier S
WHERE S.Supplier_Id (+) = P.Supplier_Id
Спасибо!
Ответы
Ответ 1
TableA LEFT OUTER JOIN TableB
эквивалентен TableB RIGHT OUTER JOIN Table A
.
В Oracle (+)
обозначает "необязательную" таблицу в JOIN. Итак, в вашем первом запросе это a P LEFT OUTER JOIN S
. В вашем втором запросе это S RIGHT OUTER JOIN P
. Они функционально эквивалентны.
В терминологии RIGHT или LEFT укажите, какая сторона соединения всегда имеет запись, а другая сторона может быть нулевой. Таким образом, в P LEFT OUTER JOIN S
, P
всегда будет иметь запись, потому что она на LEFT
, но S
может быть нулевой.
Подробнее см. этот пример с java2s.com.
Чтобы уточнить, я думаю, что я говорю, что терминология не имеет значения, поскольку она только там, чтобы помочь визуализировать. Важно то, что вы понимаете, как это работает.
ПРАВИЛЬНО против LEFT
Я видел некоторую путаницу в том, что важно при определении RIGHT vs LEFT в синтаксисе неявного соединения.
ВЛЕВОЕ ВЗАИМОДЕЙСТВИЕ
SELECT *
FROM A, B
WHERE A.column = B.column(+)
ПРАВИЛЬНАЯ ВСТРОЕННАЯ РАБОТА
SELECT *
FROM A, B
WHERE B.column(+) = A.column
Все, что я сделал, это swap-стороны терминов в предложении WHERE, но они по-прежнему функционально эквивалентны. (См. Выше в моем ответе для получения дополнительной информации об этом.) Размещение (+)
определяет RIGHT или LEFT. (В частности, если (+)
находится справа, это ЛЕВЫЙ ПРИСОЕДИНЕНИЕ. Если (+)
находится слева, это ПРАВОЕ СОЕДИНЕНИЕ.)
Типы JOIN
Два стиля JOIN - это неявные JOIN и явные JOIN. Это разные стили написания JOINs, но они функционально эквивалентны.
См. этот вопрос SO.
Неявные JOINs просто перечисляют все таблицы вместе. Условия соединения указаны в предложении WHERE.
Неявный JOIN
SELECT *
FROM A, B
WHERE A.column = B.column(+)
Явные JOINs связывают условия соединения с конкретным включением таблицы вместо предложения WHERE.
Явный JOIN
SELECT *
FROM A
LEFT OUTER JOIN B ON A.column = B.column
Эти
Неявные JOINs могут быть более трудными для чтения и понимания, и у них также есть несколько ограничений, поскольку условия соединения смешиваются в других условиях WHERE. Таким образом, неявные JOINs обычно рекомендуются в пользу явного синтаксиса.
Ответ 2
Эти два запроса выполняют OUTER JOIN
. См. Ниже
Oracle рекомендует использовать синтаксис FROM FROM OUTER JOIN а не оператор объединения Oracle. Запросы внешнего соединения, которые используют Оператор объединения Oracle (+) подчиняется следующим правилам и ограничения, которые не применяются к предложению FROM OUTER JOIN Синтаксис:
-
Вы не можете указать оператор (+) в блоке запроса, который также содержит синтаксис соединения предложения FROM.
-
Оператор (+) может отображаться только в предложении WHERE или, в контекст левой корреляции (при задании предложения ТАБЛИЦА) в 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, содержащее оператор (+), нельзя комбинировать с другое условие, использующее логический оператор ИЛИ.
-
Условие 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
Ответ 3
Я видел некоторые противоречия в ответах выше, я просто попробовал следующее в Oracle 12c, и верно следующее:
ВЛЕВОЕ ВЗАИМОДЕЙСТВИЕ
SELECT *
FROM A, B
WHERE A.column = B.column(+)
ПРАВИЛЬНАЯ ВСТРОЕННАЯ РАБОТА
SELECT *
FROM A, B
WHERE B.column(+) = A.column
Ответ 4
В этом потоке есть некорректная информация. Я скопировал и вставил неверную информацию:
ВЛЕВОЕ ВЗАИМОДЕЙСТВИЕ
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 External:
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
Обратите внимание, что это обратное тому, что выложено выше. Я полагаю, что эта книга может иметь ошибки, но я больше доверяю этой книге, чем тому, что есть в этой теме. Это учебное пособие для крика вслух...