Синтаксис соединения ANSI обеспечивает очень четкое различие между условиями JOIN и предикатами FILTER; это очень важно при написании внешних объединений. Используя таблицы emp / dept, посмотрите на результаты следующих двух внешних объединений
Q1
SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
LEFT OUTER JOIN emp e
on d.deptno = e.deptno
and loc in ('NEW YORK','BOSTON' )
;
DNAME DEPTNO ENAME MGR LOC
-------------- ---------- ---------- ---------- -------------
ACCOUNTING 10 CLARK 7839 NEW YORK
ACCOUNTING 10 KING NEW YORK
ACCOUNTING 10 MILLER 7782 NEW YORK
RESEARCH 20 DALLAS
SALES 30 CHICAGO
OPERATIONS 40 BOSTON
====
Q2
SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
LEFT OUTER JOIN emp e
on d.deptno = e.deptno
where loc in ('NEW YORK','BOSTON' )
;
DNAME DEPTNO ENAME MGR LOC
-------------- ---------- ---------- ---------- -------------
ACCOUNTING 10 CLARK 7839 NEW YORK
ACCOUNTING 10 KING NEW YORK
ACCOUNTING 10 MILLER 7782 NEW YORK
OPERATIONS 40 BOSTON
Первый пример, показанный Q1, является примером "соединения по константе". По сути, условие фильтра применяется перед выполнением внешнего соединения. Таким образом, вы исключаете строки, которые впоследствии добавляются обратно как часть внешнего соединения. Это не обязательно неправильно, но это тот запрос, который вы действительно просили? Часто требуются результаты, показанные в Q2, где фильтр применяется после (внешнего) соединения.
Существует также влияние на производительность для больших наборов данных. Во многих случаях объединение с константой должно быть разрешено оптимизатором изнутри, создав боковое представление, которое обычно можно оптимизировать только с помощью соединения с вложенным циклом, а не с помощью хеш-соединения
Для разработчиков, знакомых с синтаксисом внешнего соединения Oracle, запрос, вероятно, был бы записан как
SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
,emp e
where d.deptno = e.deptno(+)
and loc in ('NEW YORK','BOSTON' )
Этот запрос семантически эквивалентен Q2 выше.
Итак, в целом, очень важно, чтобы вы понимали разницу между предложением JOIN и предложением WHERE при написании внешних объединений ANSI.