Я думаю, что это различие лучше всего объяснить с помощью логического порядка операций в SQL , что упрощенно:
FROM
(включая объединения)
WHERE
GROUP BY
- Скопления
HAVING
WINDOW
SELECT
DISTINCT
UNION
, INTERSECT
, EXCEPT
ORDER BY
OFFSET
FETCH
Объединения - это не предложение оператора select, а оператор внутри FROM
. Таким образом, все предложения ON
, принадлежащие соответствующему оператору JOIN
, уже "произошли" логически к тому времени, когда логическая обработка достигает предложения WHERE
. Это означает, что, например, в случае LEFT JOIN
семантика внешнего соединения уже произошла к тому времени, когда применяется условие WHERE
.
Я подробно объяснил следующий пример в этом посте . При выполнении этого запроса:
SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
WHERE film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;
LEFT JOIN
на самом деле не имеет никакого полезного эффекта, потому что даже если актер не сыграл в фильме, он будет отфильтрован, так как его FILM_ID
будет NULL
и предложение WHERE
будет фильтровать такую строку. Результат примерно такой:
ACTOR_ID FIRST_NAME LAST_NAME COUNT
--------------------------------------
194 MERYL ALLEN 1
198 MARY KEITEL 1
30 SANDRA PECK 1
85 MINNIE ZELLWEGER 1
123 JULIANNE DENCH 1
т.е. так же, как если бы мы внутренне соединили две таблицы. Если мы переместим предикат фильтра в предложении ON
, теперь он станет критерием для внешнего соединения:
SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
AND film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;
Значение результата будет содержать актеров без каких-либо фильмов или без каких-либо фильмов с FILM_ID < 10
ACTOR_ID FIRST_NAME LAST_NAME COUNT
-----------------------------------------
3 ED CHASE 0
4 JENNIFER DAVIS 0
5 JOHNNY LOLLOBRIGIDA 0
6 BETTE NICHOLSON 0
...
1 PENELOPE GUINESS 1
200 THORA TEMPLE 1
2 NICK WAHLBERG 1
198 MARY KEITEL 1
Короче
Всегда ставьте свой предикат там, где это логично.