В приложении на базе 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? Я никогда раньше не видел, чтобы его использовали таким образом.
Я искал значение этих (+) в SQL-запросах для Oracle. И нет возможности искать (+) с помощью Google. Я направился в Stack Overflow, и поисковая система Stack Overflow дала мне нулевой результат для (+). Что неверно. Здесь, в Stack Overflow, есть как минимум два вопроса о значении (+). Хорошо бы поисковик поправить.
Связанный: Разница между нотацией Oracle plus (+) и нотацией ansi JOIN?
Связанный: Левое внешнее соединение с помощью + входа в Oracle 11g


Это нотация левого внешнего соединения, отличная от ANSI. Начиная с Oracle9i, запутанный синтаксис внешнего соединения с использованием обозначения «(+)» был заменен синтаксисом внешнего соединения ISO 99.
Просто придирки: стандартный синтаксис OUTER JOIN был введен в SQL-92.
Извините, ваш ответ был первым ... проголосовали за. Оставив шахту вверх, так как в ней есть дополнительная информация re: left vs right outer.
В зависимости от того, с какой стороны "=" стоит знак "(+), он обозначает соединение ЛЕВОЕ ВНЕШНЕЕ или ПРАВО ВНЕШНЕЕ (в данном случае это левое внешнее соединение). Это старый синтаксис Oracle, который иногда предпочитают люди, которые выучили его первыми, так как им нравится, что это делает их код короче.
Лучше не использовать его для удобства чтения.
Спасибо за дополнительный лакомый кусочек об ориентации между (+) и =.
- .5 для того, чтобы сказать, что длиннее, более читабельно. a ++ труднее читать, чем a = a + 1. Я думаю, что это намного проще, если вы знаете, что это означает. Если вы не знаете, что это значит, откажитесь от моего кода.
@Mark - Я программировал на Perl как на родном языке последние 8 лет. Если вы не усвоили разницу между коротким и непонятным, пожалуйста, не трогайте МОЙ код!
К сожалению, синтаксис соединения ANSI недоступен в Oracle 8. Поэтому в этом случае вам нужно придерживаться синтаксиса (+).
К сожалению, MATERIALIZED VIEW с опциями FAST REFRESH ON COMMIT не поддерживает ANSI JOINS (Oracle 11). Так что в этом случае вам все равно понадобится синтаксис (+).
Как утверждали другие, синтаксис (+) является устаревшим, проприетарным синтаксисом, который Oracle использовал в течение многих лет для достижения тех же результатов, что и OUTER JOIN. Я предполагаю, что они приняли свой собственный синтаксис до того, как SQL-92 остановился на стандартном синтаксисе.
Запрос, эквивалентный показанному вами, с использованием стандартного синтаксиса SQL OUTER JOIN (который теперь поддерживается всеми основными реализациями СУБД) будет следующим:
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 в результате запроса.Следует отметить, что классическая нотация Oracle не является интуитивно понятной, и ее лучше избегать с точки зрения ясности кода и удобства обслуживания.
Чтобы проиллюстрировать этот момент, я включил этот пример.
Чтобы достичь LEFT outer join между таблицами A и B, можно было бы ожидать, что таблица слева, которая является A, должна иметь рядом с собой оператор (+). Это имело бы смысл, поскольку мы хотим обозначить, что будем включать все строки A независимо от успеха в критерии соединения с B. Однако это не так, и соединение достигается следующим образом
select b.age, a.name
from Employees a, EmployeeUNI b
where a.id = b.id(+)
Я предпочитаю явную версию ANSI SQL:
select b.age, a.name
From Employees a
LEFT outer join EmployeeUNI b
on a.id = b.id
Оба метода приводят к одному и тому же результату, однако подход ANSI не связан с риском того, что начинающий программист ошибочно поместит (+) в неправильное место.
Существуют также устаревшие операторы TSQL (SQL Server)
*=и=*. Та же лодка.