Левое внешнее объединение с помощью знака + в Oracle 11g
540887 просмотра
4 ответа
Кто-нибудь может сказать мне, являются ли ниже 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 Источник Размещён: 12.11.2019 09:45
Ответы (4)
181 плюса
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:028 плюса
Эти два запроса выполняются 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:012 плюса
Я видел некоторые противоречия в ответах выше, я только что попробовал следующее на 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
-2 плюса
В этой теме есть неверная информация. Я скопировал и вставил неверную информацию:
ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ
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Вопросы из категории :
- sql Проверить наличие изменений в таблице SQL Server?
- sql Обменять уникальные индексированные значения столбцов в базе данных
- sql Как работает индексация базы данных?
- sql Как индексировать столбец базы данных
- sql Как разбить строку, чтобы я мог получить доступ к элементу x?
- sql Удалить все таблицы, имена которых начинаются с определенной строки
- sql В какой момент кто-то решит переключить системы баз данных
- sql Как выбрать n-ую строку в таблице базы данных SQL?
- sql Как запросить случайную строку в SQL?
- sql Лучший способ инкапсулировать сложную логику курсора Oracle PL / SQL в виде представления?
- oracle11g Как узнать количество дней между двумя датами в Oracle 11g?
- oracle11g Функция сна в ORACLE
- oracle11g Oracle Instance Client Light (odac 11) и наборы символов
- oracle11g Как узнать, когда в Oracle была создана конкретная таблица?
- oracle11g ORA-29283: недопустимая файловая операция ORA-06512: в «SYS.UTL_FILE», строка 536
- oracle11g ORA-01034: ORACLE недоступен ORA-27101: область общей памяти не существует
- oracle11g Левое внешнее объединение с помощью знака + в Oracle 11g
- oracle11g Невозможно установить Oracle 11g в Windows 7
- oracle11g Проблема сравнения строк в PL / SQL Oracle
- oracle11g Как использовать функцию Oracle LISTAGG с уникальным фильтром?