Оператор Oracle «(+)»

155

Я проверяю некоторые старые операторы SQL с целью их документирования и, возможно, улучшения.

СУБД Oracle

Я не понял утверждение, которое читалось так:

select ...
from a,b
where a.id=b.id(+)

Я запутался в (+)операторе и не смог получить его ни на одном форуме ... (поиск + в кавычках тоже не помог).

Во всяком случае, я использовал «Объяснить план» SQLDeveloper и получил вывод о том HASH JOIN, RIGHT OUTER, что и т. Д.

Будет ли какая-либо разница, если я удалю (+)оператор в конце запроса? Должна ли база данных удовлетворять некоторым условиям (например, иметь некоторые индексы и т. Д.), Прежде чем ее (+)можно будет использовать ?? Было бы очень полезно, если бы вы могли дать мне простое понимание или несколько хороших ссылок, где я могу прочитать об этом.

Спасибо!

Sekhar
источник
1
Это не оператор. Это просто часть синтаксиса, которая влияет на то, что делает JOIN.
Philipxy

Ответы:

187

Это специфическая для Oracle нотация для OUTER JOIN, потому что формат ANSI-89 (с использованием запятой в предложении FROM для разделения ссылок на таблицы) не стандартизировал OUTER-соединения.

Запрос будет переписан в синтаксисе ANSI-92 как:

   SELECT ...
     FROM a
LEFT JOIN b ON b.id = a.id

Эта ссылка довольно хорошо объясняет разницу между JOIN .


Следует также отметить, что, хотя (+)работает, Oracle рекомендует не использовать его :

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

OMG пони
источник
79
Совершенно верно. Чтобы держать (+) прямо в моей голове (левая сторона и правая сторона), мне нравится думать о (+) как о «добавлении значений NULL, если совпадение не найдено». Например, «a.id = b.id (+)» означает, что b.id должен быть равен NULL, если нет совпадения с a.id.
пляж
спасибо .. я думаю, добавление его из условия должно дать тот же результат !!
Киран С
Возможно, вы захотите получить ссылку на официальную документацию Oracle: docs.oracle.com/html/A95915_01/sqopr.htm
Варган
27

Оператор (+) указывает на внешнее соединение. Это означает, что Oracle по-прежнему будет возвращать записи с другой стороны объединения, даже если совпадений нет. Например, если a и b имеют emp и dept, и вы можете назначить сотрудников, не назначенных в отдел, то следующее утверждение вернет сведения обо всех сотрудниках, независимо от того, были ли они назначены в отдел.

select * from emp, dept where emp.dept_id=dept.dept_id(+)

Короче говоря, удаление (+) может иметь значение, но вы можете не заметить какое-то время в зависимости от ваших данных!

хот-дог
источник
25

В Oracle (+) обозначает «необязательную» таблицу в JOIN. Так что в вашем запросе

SELECT a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id(+)

это ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ таблицы 'b' к таблице 'a'. Он вернет все данные таблицы «а» без потери своих данных, когда другая сторона (необязательная таблица «б») не имеет данных.

Схема левого внешнего соединения

Современный стандартный синтаксис для того же запроса будет

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b ON a.id=b.id

или с сокращением для a.id=b.id(не поддерживается всеми базами данных):

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b USING(id)

Если вы удалите (+), то это будет обычный запрос внутреннего соединения

Более старый синтаксис, как в Oracle, так и в других базах данных:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id

Более современный синтаксис:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
INNER JOIN b ON a.id=b.id

Или просто:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
JOIN b ON a.id=b.id

Схема внутреннего соединения

Он будет возвращать только те данные, в которых значение «id» таблиц «a» и «b» одинаково, что означает общую часть.

Если вы хотите сделать ваш запрос Правильным

Это то же самое, что LEFT JOIN, но переключает, какая таблица является необязательной.

Схема правого внешнего соединения

Старый синтаксис Oracle:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id(+)=b.id

Современный стандартный синтаксис:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
RIGHT JOIN b ON a.id=b.id

Ref & help:

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:6585774577187

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

https://www.w3schools.com/sql/sql_join_left.asp

Г-н Салман Фахад Известный
источник
Метки круга «table1» и «table2» - это чепуха. Простейшее значение для элементов круга - выходные строки. Тогда левый полумесяц содержит расширенные нулями строки таблицы 1, а правый полумесяц содержит расширенные нулями строки таблицы 2. Другие значения для кругов неясны. Что именно вы думаете, диаграммы означают? Почему вы вставили их, кроме слепого копирования (плохих) презентаций других людей?
Philipxy
Теперь вы пометили круги a & b. Круги не являются строками a & b. Левый и правый круги могут быть разумно помечены как строки левого соединения b и правого соединения b. Более того, вы не описываете, что представляют собой эти окруженные строки с точки зрения ввода. Подумайте сами, что в кругах. Если вы собираетесь наклеивать ярлыки a & b на круги, четко объясните словами, какое отношение имеет каждый ярлык к своему кругу. (Нет простой причины пометить их как a & b.) Хорошо, что вы правильно обозначили зеленые зоны.
philipxy
6

На практике символ + помещается непосредственно в условный оператор и сбоку необязательной таблицы (той, которая может содержать пустые или нулевые значения в условном выражении).

солнечно
источник
(+) Ставится сразу справа от имени столбца. Этот ответ не ясен по этому поводу. Что должно означать «на практике»? (Риторика.) (И вы, вероятно, не имеете в виду «заявление».)
philipxy