当表左连接时where子句和on子句之间的区别是什么?

Sle*_*ght 19 sql where-clause

SQL1:

select t1.f1,t2.f2 
from t1 
   left join t2 on t1.f1 = t2.f2 and t1.f2=1 and t1.f3=0 
Run Code Online (Sandbox Code Playgroud)

SQL2:

select t1.f1,t2.f2 
from t1 
  left join t2 on t1.f1 = t2.f2 
where t1.f2=1 and t1.f3=0
Run Code Online (Sandbox Code Playgroud)

不同之处在于where和on子句,是否有相同的返回结果?有什么区别?DBMS以同样的方式运行它们吗?谢谢.

小智 24

where条款适用于整个结果集; on clause仅适用于有问题的联接.

在提供的示例中,所有附加条件都与连接内侧的字段相关 - 因此在此示例中,两个查询实际上是相同的.

但是,如果您在连接外侧的表中包含了一个条件,则会产生显着差异.

您可以从以下链接获得更多信息:http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause

例如:

select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 and t2.f4=1

select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 where t2.f4=1
Run Code Online (Sandbox Code Playgroud)

- 做不同的事情 - 前者将连接到t2记录,其中f4是1,而后者有效地被转回到t2的内连接.


Mas*_*uso 8

第一个查询比第二个查询更快,因为连接条件比第二个查询更具体:返回使用where子句过滤的记录是没有意义的(最好不要将它们全部返回 - query1 )

无论如何,它真的取决于查询优化器.

看看下面的内容:

JOIN比WHERE更快吗?


Luk*_*der 5

在考虑 SQL 语法时,了解SQL 操作的逻辑顺序很重要。JOIN是子句中的运算符(并且ON属于相关的JOINFROM。该FROM子句是第一个逻辑执行的操作(优化器仍然可以选择重新排序)。

在您的示例中,实际上并没有什么区别,但是很容易构建一个,正如我在这篇博客文章中展示的关于ONWHEREin之间的区别OUTER JOIN(博客文章中的示例使用Sakila 数据库):

第一次查询

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;
Run Code Online (Sandbox Code Playgroud)

产量:

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
Run Code Online (Sandbox Code Playgroud)

因为我们在WHERE子句中过滤了外部连接表,所以LEFT JOIN实际上变成了INNER JOIN. 为什么?因为如果我们有一个没有在电影中出演的演员,那么该演员的唯一行会有fa.film_id IS NULLfa.film_id < 10因此谓词会产生NULL。这样的演员被排除在结果之外,就像一个INNER JOIN.

第二次查询

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
Run Code Online (Sandbox Code Playgroud)

产量:

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
Run Code Online (Sandbox Code Playgroud)

现在,没有电影的演员被包含在结果中,因为fa.film_id < 10谓词是LEFT JOIN'sON谓词的一部分

结论

始终将谓词放在逻辑上最有意义的地方。

  • 它们是您JOIN运营的一部分吗?将它们放入ON
  • 它们是否对您的整个JOIN产品进行过滤?将它们放入WHERE