Разница между нотацией Oracle plus (+) и нотацией ANSI JOIN?


в чем разница между использованием нотации oracle plus (+) по стандарту ansi join нотации?

есть ли разница в производительности?

это плюс нотация устарела?

8 69

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, связанные с информацией. Например: запросы, связанные с основными средствами

  1. использование явных соединений вместо неявных (независимо от того, являются ли они внешними соединениями или нет) заключается в том, что гораздо проще случайно создать декартово произведение с неявными соединениями. С явными соединениями вы не можете "случайно" создать его. Чем больше таблиц, тем выше риск, что вы пропустите одно условие соединения.
  2. в основном (+) сильно ограничен по сравнению с ANSI присоединяется. Кроме того, он доступен только в Oracle, тогда как синтаксис соединения ANSI поддерживается всеми основными СУБД
  3. SQL не начнет работать лучше после перехода на синтаксис ANSI-это просто другой синтаксис.
  4. Oracle настоятельно рекомендует использовать более гибкий синтаксис соединения предложений FROM, показанный в предыдущем примере. В прошлом были некоторые ошибки с синтаксисом ANSI, но если вы идете с последними 11.2 или 12.1, которые уже должны быть исправлены.
  5. использование операторов JOIN гарантирует, что ваш SQL-код совместим с ANSI и, таким образом, позволит интерфейсное приложение будет более легко портироваться для других платформ баз данных.
  6. условия соединения имеют очень низкую селективность на каждой таблице и высокую селективность на кортежах в теоретическом перекрестном продукте. Условия в предложении where, как правило, имеют гораздо более высокую селективность.
  7. Oracle внутренне преобразует синтаксис ANSI в синтаксис ( + ), вы можете увидеть, как это происходит в разделе информации о предикатах плана выполнения.