在考虑 SQL 语法时,理解the logical order of SQL operations 很重要。 JOIN 是FROM 子句中的运算符(并且ON 属于相关的JOIN)。 FROM 子句是第一个在逻辑上执行的操作(优化器仍然可以选择重新排序)。
在您的示例中,没有真正的区别,但很容易构造一个,as I've shown in this blog post about the difference between ON and WHERE in OUTER JOIN(博客文章中的示例使用Sakila database):
第一次查询
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 fa.film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;
产量:
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
因为我们在WHERE 子句中过滤了外部联接表,所以LEFT JOIN 有效地变成了INNER JOIN。为什么?因为如果我们有一个没有在电影中演出的演员,那么该演员的唯一行将有fa.film_id IS NULL,因此fa.film_id < 10 谓词将产生NULL。这样的参与者被排除在结果之外,就像INNER JOIN一样。
第二次查询
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 fa.film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;
产量:
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
现在,结果中包含没有电影的演员,因为fa.film_id < 10 谓词是LEFT JOIN 的ON 谓词的一部分
结论
始终将谓词放在它们逻辑上最有意义的地方。
- 它们是您的
JOIN 操作的一部分吗?把它们放在ON
- 它们是否对您的整个
JOIN 产品进行过滤?把它们放在WHERE