Разница между нотацией Oracle plus (+) и нотацией ANSI JOIN?
в чем разница между использованием нотации oracle plus (+)
по стандарту ansi join
нотации?
есть ли разница в производительности?
это плюс нотация устарела?
8 ответов:
AFAIK, the
(+)
нотация присутствует только для обратной совместимости, потому что Oracle дебютировал до того, как был введен стандарт ANSI для соединений. Это специфично для Oracle, и вы должны избегать его использования в новом коде, когда есть эквивалентная совместимая со стандартами версия.Edit:кажется, есть различия между этими двумя, и
(+)
нотация имеет ограничения, которые синтаксис соединения ANSI не имеет. Себя оракулом не рекомендуется использовать(+)
нотации. Полное описание здесь Справочник по языку SQL базы данных Oracle® 11g релиз 1 (11.1):Oracle рекомендует использовать
FROM
п.OUTER JOIN
синтаксис, а не оператор Oracle join. Внешние запросы соединения, использующие оператор Oracle join(+)
действуют следующие правила и ограничения, которые не распространяются наFROM
п.OUTER JOIN
синтаксис:
- вы не можете указать
(+)
оператор в блоке запроса, который также содержитFROM
синтаксис соединения предложений.- The
(+)
оператор может появиться только вWHERE
предложение или, в контексте левой корреляции (при указанииTABLE
предложения) вFROM
предложение, и может применяться только к столбцу таблицы или представления.если A и B соединены несколькими условиями соединения, то вы должны использовать
(+)
оператор во всех этих условиях. Если вы этого не сделаете, то Oracle Database вернет только строки, полученные в результате простого соединения, но без предупреждения или ошибки, чтобы сообщить вам, что у вас нет результатов внешнего соединения.The
(+)
оператор не создает внешнее соединение, если вы указываете одну таблицу во внешнем запросе и другую таблицу во внутреннем запросе.вы не можете использовать
(+)
оператор к внешнему-присоединить таблицу к себе, хотя самостоятельные соединения действительны.например, недопустимо следующее утверждение:
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;
The
(+)
оператор может быть применен только к столбцу, а не произвольное выражение. Однако, произвольное выражение может содержать один или несколько столбцов, помеченных(+)
оператора.A
WHERE
условие, содержащее(+)
оператор не может быть объединен с другим условием с помощьюOR
логический оператор.A
WHERE
условие не может использоватьIN
условие сравнения для сравнения столбца, отмеченного символом(+)
оператор с выражением.если
WHERE
предложение содержит условие, которое сравнивает столбец из таблицы B с константой, а затем(+)
оператор должен быть применен к столбцу, чтобы Oracle возвращал строки из таблицы A, для которых он создал значения NULL для этого столбца. В противном случае Oracle возвращает только результаты простого соединения.в запросе, который выполняет внешние соединения более двух пар таблиц, одна таблица может быть пустой таблицы, созданные только для одной таблицы. По этой причине вы не можете применить
(+)
оператор для столбцов B в условии соединения для A и B и условие соединения для B и C. см.SELECT
синтаксис внешнего соединения.
нотация по-прежнему поддерживается с Oracle 10 (и я считаю, что 11). Его использование считается "старомодным", а также не так переносимо, как синтаксис ANSI JOIN. Он также считается гораздо менее читаемым, хотя, если вы пришли из + фона, привыкание к ANSI JOIN может занять немного времени. Важно знать, прежде чем бросать кирпичи в Oracle, что они разработали свой синтаксис + до того, как комитет ANSI завершил определения для присоединяется.
нет никакой разницы в производительности; они выражают одно и то же.
Edit: по "не как портативный" я должен был сказать "поддерживается только в Oracle SQL"
Я согласен с ответом Тони Миллера и хотел бы добавить, что есть также несколько вещей, которые вы не можете сделать с (+) synthax:
- вы не можете полностью внешний объединить две таблицы, вы должны сделать это вручную с объединением всех двух соединений,
- вы не можете внешне присоединить таблицу к двум или более таблицам, вы должны вручную создать подзапрос (т. е.:
b.id = a.id (+) AND c.id = a.id (+)
не является приемлемым предложением)
наиболее полный ответ, очевидно, является одним из nagul.
дополнение для тех, кто ищет быстрый перевод/сопоставление с синтаксисом ANSI:
-- -- INNER JOIN -- SELECT * FROM EMP e INNER JOIN DEPT d ON d.DEPTNO = e.DEPTNO; -- Synonym in deprecated oracle (+) syntax SELECT * FROM EMP e, DEPT d WHERE d.DEPTNO = e.DEPTNO; -- -- LEFT OUTER JOIN -- SELECT * FROM EMP e LEFT JOIN DEPT d ON d.DEPTNO = e.DEPTNO; -- Synonym in deprecated oracle (+) syntax SELECT * FROM EMP e, DEPT d WHERE d.DEPTNO (+) = e.DEPTNO; -- -- RIGHT OUTER JOIN -- SELECT * FROM EMP e RIGHT JOIN DEPT d ON d.DEPTNO = e.DEPTNO; -- Synonym in deprecated oracle (+) syntax SELECT * FROM EMP e, DEPT d WHERE d.DEPTNO = e.DEPTNO(+); -- -- CROSS JOIN -- SELECT * FROM EMP e CROSS JOIN DEPT d; -- Synonym in deprecated oracle (+) syntax SELECT * FROM EMP e, DEPT d; -- -- FULL JOIN -- SELECT * FROM EMP e FULL JOIN DEPT d ON d.DEPTNO = e.DEPTNO; -- Synonym in deprecated oracle (+) syntax !NOT WORKING! SELECT * FROM EMP e, DEPT d WHERE d.DEPTNO (+) = e.DEPTNO(+);
одна из веских причин использовать ANSI синтаксис над старым синтаксис Oracle join это, есть нулевые шансы случайно создать декартова произведения. С большим количеством таблиц, есть шанс пропустить подразумевается join с более старым синтаксисом Oracle join, однако, с синтаксисом ANSI вы не можете пропустить ни одного соединения, как вы должны явно упоминать о них.
разницу между Oracle outer join синтаксис и синтаксис 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);
ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ -
перед собственной поддержкой hash full outerjoin в 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);
посмотреть этой.
Oracle ( + ) notation используется только в Oracle, которая составляет поставщиком. И,ANSI standared Join notation может быть используется в любых СУБД (например, Sql Server, MySql и т. д.). В противном случае нет никакой разницы между нотацией Oracle (+) и нотацией ANSI standared Join.
Если вы используете стандартную нотацию соединения ANSI в своем Sql-запросе, вы можете использовать тот же запрос в любой СУБД. и, если вы не перенос базы данных от Oracle к любой другой СУБД в таком состоянии ты должен использовать синтаксис ANSI.
Я использую (+) нотацию, потому что почти все связанные с Oracle Apps R12 запросы основаны на этом. Я не видел ни одного SQL-запроса со стандартным выражением "join" в запросах Oracle APPS(даже те, которые предоставлены самим Oracle). Если вы не верите мне, просто google любые приложения Oracle, связанные с информацией. Например: запросы, связанные с основными средствами
- использование явных соединений вместо неявных (независимо от того, являются ли они внешними соединениями или нет) заключается в том, что гораздо проще случайно создать декартово произведение с неявными соединениями. С явными соединениями вы не можете "случайно" создать его. Чем больше таблиц, тем выше риск, что вы пропустите одно условие соединения.
- в основном (+) сильно ограничен по сравнению с ANSI присоединяется. Кроме того, он доступен только в Oracle, тогда как синтаксис соединения ANSI поддерживается всеми основными СУБД
- SQL не начнет работать лучше после перехода на синтаксис ANSI-это просто другой синтаксис.
- Oracle настоятельно рекомендует использовать более гибкий синтаксис соединения предложений FROM, показанный в предыдущем примере. В прошлом были некоторые ошибки с синтаксисом ANSI, но если вы идете с последними 11.2 или 12.1, которые уже должны быть исправлены.
- использование операторов JOIN гарантирует, что ваш SQL-код совместим с ANSI и, таким образом, позволит интерфейсное приложение будет более легко портироваться для других платформ баз данных.
- условия соединения имеют очень низкую селективность на каждой таблице и высокую селективность на кортежах в теоретическом перекрестном продукте. Условия в предложении where, как правило, имеют гораздо более высокую селективность.
- Oracle внутренне преобразует синтаксис ANSI в синтаксис ( + ), вы можете увидеть, как это происходит в разделе информации о предикатах плана выполнения.