原文:https://www.cnblogs.com/guanshan/articles/guan062.html

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
在使用left jion时,on和where条件的区别如下:
1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

假设有两张表:
表1:tab2
id size
1 10
2 20
3 30
表2:tab2 
size name
10 AAA
20 BBB
20 CCC

两条SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)

第一条SQL的过程:1、中间表on条件: tab1.size = tab2.size tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 20 BBB
2 20 20 CCC
3 30 (null) (null)

2、再对中间表过滤where 条件:tab2.name=’AAA’ tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA

第二条SQL的过程:1、中间表on条件: tab1.size = tab2.size and tab2.name=’AAA’(条件不为真也会返回左表中的记录) tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 (null) (null)
3 30 (null) (null)

其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner join没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。on为了反映外连接中一方的全连接,而where没有这个功能,内连接配对是可以的。

==================================================================================

on、where、having的区别

on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。有时候如果这先后顺序不影响中间结果的话,那最终结果是相同的。但因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的。

根据上面的分析,可以知道where也应该比having快点的,因为它过滤数据后才进行sum,所以having是最慢的。但也不是说having没用,因为有时在步骤3还没出来都不知道那个记录才符合要求时,就要用having了。

在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢。

如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。

在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什幺时候起作用,然后再决定放在那里

JOIN联表中ON,WHERE后面跟条件的区别

对于JOIN的连表操作,这里就不细述了,当我们在对表进行JOIN关联操作时,对于ON和WHERE后面的条件,不清楚大家有没有注意过,有什幺区别,可能有的朋友会认为跟在它们后面的条件是一样的,你可以跟在ON后面,如果愿意,也可以跟在WHERE后面。它们在ON和WHERE后面究竟有一个什幺样的区别呢?
在JOIN操作里,有几种情况。LEFT JOIN,RIGHT JOIN,INNER JOIN等。

为了清楚的表达主题所描述的问题,我简要的对LEFT,RIGHT,INNER这几种连接方式作一个说明。

下面就拿一个普通的博客系统的日志表(post)和分类表(category)来描述吧。

这里我们规定有的日志可能没有分类,有的分类可能目前没有属于它的文章。

1.LEFT JOIN:(保证找出左联表中的所有行)
查出所有文章,并显示出他们的分类:
SELECT p.title,c.category_name 
FROM post p 
LEFT JOIN category c ON p.cid = c.cid2.

RIGHT JOIN:(保证找出右联表中的所有行)
查询所有的分类,并显示出该分类所含有的文章数。
SELECT COUNT(p.id),c.category_name 
FROM post p 
RIGHT JOIN category c ON p.pid = c.cid3.

INNER JOIN:(找出两表中关联相等的行)
查询有所属分类的日志。(即那些没有所性分类的日志文章将不要我们的查询范围之内)。
SELECT p.title,c.category_name 
FROM post p 
INNER JOIN category c ON p.cid = c.cid.这种情况和直接两表硬关联等价。

现在我们回过头来看上面的问题。对于第一种情况,如果我们所ON 的条件写在WHERE 后面,将会出现什幺情况呢?即:

SELECT p.title,c.category_name 
FROM post p 
LEFT JOIN category c 
WHERE p.cid = c.cid

对于第二种情况,我们同样按照上面的书写方式。

SELECT COUNT(p.id),c.category_name 
FROM post p 
RIGHT JOIN category c 
WHERE p.pid = c.cid

如果运行上面的SQL语句,就会发现,它们已经过滤掉了一些不满足条件的记录,可能在这里,大家会产生疑问了,不是用了LEFT和RIGHT吗?它们可以保证左边或者右边的所有行被全部查询出来,为什幺现在不管用了呢?对于出现这种的问题,呵呵!是不是觉得有些不可思议。出现这种的问题,原因就在WHERE和ON这两个关键字后面跟条件。
好了,现在我也不调大家味口了,给大家提示答案吧。
对于JOIN参与的表的关联操作,如果需要不满足连接条件的行也在我们的查询范围内的话,我们就必需把连接条件放在ON后面,而不能放在WHERE后面,如果我们把连接条件放在了WHERE后面,那幺所有的LEFT,RIGHT,等这些操作将不起任何作用,对于这种情况,它的效果就完全等同于INNER连接。对于那些不影响选择行的条件,放在ON或者WHERE后面就可以。
记住:所有的连接条件都必需要放在ON后面,不然前面的所有LEFT,和RIGHT关联将作为摆设,而不起任何作用。

SQL中ON和WHERE的区别(转)的更多相关文章

  1. SQL中ON和WHERE的区别

    SQL中ON和WHERE的区别 - 邃蓝星空 - 博客园 https://www.cnblogs.com/guanshan/articles/guan062.html

  2. SQL中存储过程和函数的区别

    转:https://www.cnblogs.com/jacketlin/p/7874009.html 本质上没区别.只是函数有如:只能返回一个变量的限制.而存储过程可以返回多个. 而函数是可以嵌入在s ...

  3. 面试问题 - SQL 中存储过程与函数的区别

    SQL 中的存储过程与函数没有本质上的区别 函数 -> 只能返回一个变量. 函数可以嵌入到sql中使用, 可以在select 中调用, 而存储过程不行.  但函数也有着更多的限制,比如不能使用临 ...

  4. SQL中INEXISTS和IN 的区别和联系

    SET NOCOUNT ON , SET NOCOUNT OFF当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数).当 SET NOCOUNT 为 ...

  5. SQL中Where与Having的区别

    “Where” 是一个约束声明,使用Where来约束来之数据库的数据,Where是在结果返回之前起作用的,且Where中不能使用聚合函数. “Having”是一个过滤声明,是在查询返回结果集以后对查询 ...

  6. SQL中 WHERE与HAVING的区别

    SQL语句中的Having子句与where子句之区别 在说区别之前,得先介绍GROUP BY这个子句,而在说GROUP子句前,又得先说说“聚合函数”——SQL语言中一种特殊的函数.例如SUM, COU ...

  7. SQl中drop与truncate的区别

    在对SQL的表操作时,我们因不同的需求做出相应的操作. 我来对比一下truncate table '表明'与drop table '表格名'的区别,跟大家一起学习. drop table '表格名'- ...

  8. SQL 中having 和where的区别分析

    在select语句中可以使用groupby子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集 在select语句中可以使用groupby子 ...

  9. sql中Statement与PreparedStatement的区别

    1.Statement用于执行静态sql语句,在执行时,必须指定一个事先准备好的sql语句,也就是说sql语句是静态的. 2.PrepareStatement是预编译的sql语句对象,sql语句被预编 ...

随机推荐

  1. noj算法 素数环 回溯法

    描述: 把1到20这重新排列,使得排列后的序列A满足:a. 任意相邻两个数之和是素数b. 不存在满足条件a的序列B使得:A和B的前k(0 <= k <= 19)项相同且B的第k+1项比A的 ...

  2. RDay2-Problem 2 B

    题目描述 小明家有n个信箱,前前后后来送信和取信的总次数为q,称为q次访问,其中这q次访问分成三种类型. 1:邮递员送来了一封信,放在了x号信箱. 2:小明取走了x号信箱的所有信(x信箱可能已经没有信 ...

  3. An overview of network penetration testing

    1. an SQLi vulnerability will allow you  to do the  following query the database using select statem ...

  4. EChart 文字大小调整 饼状图为例

    一.EChart图中的文字调整(以饼图为例) 二.源码: { "title": { "text": "", "subtext&qu ...

  5. Servlet(九):web.xml文件和server.xml文件

    Web.xml 文件使用总结:作用: 存储项目相关的配置信息,保护 Servlet.解耦一些数据对程序的依赖.使用位置: 每个 Web 项目中Tomcat 服务器中(在服务器目录 conf 目录中)区 ...

  6. get、put、post、delete含义与区别

    1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数据,不会影响资源的内容,即该请求不会产生副作用.无论进行多少次操 ...

  7. javascript事件之调整大小(resize)事件

    当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件. var EventUtil = { addHandler: function (element, type, handler) { ...

  8. 201771010126 王燕《面向对象程序设计(java)》第八周学习总结

    实验六 接口的定义与使用 实验时间 2018-10-18 1.实验目的与要求 (1) 掌握接口定义方法 JAVA中通过interface关键字定义接口: 接口中只能定义public static fi ...

  9. __x__(35)0908第五天__opacity 透明度

    opacity 透明度 设置一个  0 - 1 之间的值. opacity: 0;    完全透明 opacity: 0.5    半透明 opacity: 1;    完全不透明 缺点: IE8及以 ...

  10. (89)Wangdao.com第二十二天_JavaScript DocumentFragment 节点

    DocumentFragment 节点 代表一个文档的片段,本身就是一个完整的 DOM 树形结构. 它没有父节点,.parentNode 返回 null 可以插入任意数量的子节点. 不属于当前文档,操 ...