Oracle: Что делает `(+)` в предложении WHERE?
В приложении Oracle, которое мы переносим (обобщенно), найдено следующее:
SELECT
Table1.Category1,
Table1.Category2,
count(*) as Total,
count(Tab2.Stat) AS Stat
FROM Table1, Table2
WHERE (Table1.PrimaryKey = Table2.ForeignKey(+))
GROUP BY Table1.Category1, Table1.Category2
Что делает (+)
в предложении WHERE? Я никогда раньше не видел, чтобы это использовалось раньше.
Ответы
Ответ 1
В зависимости от того, какая сторона "=" включена (+), она обозначает объединение LEFT OUTER или RIGHT OUTER (в данном случае это левое внешнее соединение). Это старый синтаксис Oracle, который иногда предпочтительнее людьми, которые узнали это сначала, так как им это нравится, что делает их код короче.
Лучше не использовать его, хотя для удобства чтения.
Ответ 2
Как утверждали другие, синтаксис (+)
является устаревшим, проприетарным синтаксисом, который Oracle использовал в течение многих лет для достижения тех же результатов, что и OUTER JOIN
. Я предполагаю, что они приняли свой собственный синтаксис до того, как SQL-92 принял решение о стандартном синтаксисе.
Эквивалентный запрос к тому, который вы показали, используя стандартный синтаксис SQL OUTER JOIN
(который теперь поддерживается всеми основными реализациями RDBMS), будет следующим:
SELECT
Table1.Category1,
Table1.Category2,
COUNT(*) AS Total,
COUNT(Table2.Stat) AS Stat
FROM Table1
LEFT OUTER JOIN Table2 ON (Table1.PrimaryKey = Table2.ForeignKey)
GROUP BY Table1.Category1, Table1.Category2;
Это означает:
- Все строки из
Table1
включены в результат запроса.
- Если в
Table2
есть соответствующие строки, укажите эти строки (повторяя содержимое из Table1
, если в Table2
есть несколько совпадающих строк).
- Если в
Table2
нет соответствующих строк, используйте NULL
для всех столбцов Table2
в результате запроса.
Ответ 3
Это внешняя нотация без ANSI. Начиная с Oracle9i, смущающий внешний синтаксис соединения с использованием нотации '(+) был заменен синтаксисом внешнего соединения ISO 99.