sql连接查询中on筛选与where筛选的区别
sql查询这个东西, 要说它简单, 可以很简单, 通常情况下只需使用增删查改配合编程语言的逻辑表达能力,就能实现所有功能。 但是增删查改并不能代表sql语句的所有, 完整的sql功能会另人望而生畏。 就拿比普通增删查改稍微复杂一个层次的连接查询来说, 盲目使用, 也会出现意料之外的危险结果,导致程序出现莫名其妙的BUG。
在连接查询语法中,另人迷惑首当其冲的就要属on筛选和where筛选的区别了, 在我们编写查询的时候, 筛选条件的放置不管是在on后面还是where后面, 查出来的结果总是一样的, 既然如此,那为什么还要多此一举的让sql查询支持两种筛选器呢? 事实上, 这两种筛选器是存在差别的,只是如果不深挖不容易发现而已。
sql中的连接查询分为3种, cross join,inner join,和outer join , 在 cross join和inner join中,筛选条件放在on后面还是where后面是没区别的,极端一点,在编写这两种连接查询的时候,只用on不使用where也没有什么问题。因此,on筛选和where筛选的差别只是针对outer join,也就是平时最常使用的left join和right join。
来看一个示例,有两张数据表,结构和数据如图所示
表main

表ext

可以把这两张表看作是用来存放用户信息的, main放置主要信息,ext表放置附加信息,两张表的关系是1对1的,以id字符作为对应关系键。现在我们需要将地址不为杭州的所有用户信息筛选出来,结果中需要包含main表和ext表的所有字段数据。
select * from main left JOIN exton main.id = ext.id and address <> '杭州'
闭上眼睛, 请用大脑人肉运行一下这段SQL, 想象一下是什么结果。

当把 address <> '杭州' 这个筛选条件放在on之后,查询得到的结果似乎跟我们预料中的不同,从结果中能看出,这个筛选条件好像只过滤掉了ext表中对应的记录,而main表中的记录并没有被过滤掉,也就是上图中标记为红色的那条记录。outer join相对于inner join的一个主要特性就是以一侧的表为基础,但是在这里以左表为基这一点却可以无视筛选条件,这未免也太霸道了一些。
把查询语句稍微改动一下,将地址的筛选条件从on转移至where
select * from main left JOIN ext on main.id = ext.id where address <> '杭州'
结果就如我们预期的那样了

造成这种结果上的差异要从outer join查询的逻辑查询的各个阶段说起。总的来说,outer join 的执行过程分为4步
1、先对两个表执行交叉连接(笛卡尔积)
2、应用on筛选器
3、添加外部行
4、应用where筛选器
就拿上面不使用where筛选器的sql来说,执行的整个详细过程如下
第一步,对两个表执行交叉连接,结果如下,这一步会产生36条记录(此图显示不全)

第二步,应用on筛选器。筛选器中有两个条件,main.id = ext.id and address<> '杭州',符合要求的记录如下

这似乎正是我们期望中查询的结果,然而在接下来的步骤中这个结果会被打乱
第三步,添加外部行。outer join有一个特点就是以一侧的表为基,假如另一侧的表没有符合on筛选条件的记录,则以null替代。在这次的查询中,这一步的作用就是将那条原本应该被过滤掉的记录给添加了回来

是不是不种画蛇添足的感觉, 结果就成了这样

第四步,应用where筛选器
在这条问题sql中,因为没有where筛选器,所以上一步的结果就是最终的结果了。
而对于那条地址筛选在where条件中的sql,这一步便起到了作用,将所有地址不属于杭州的记录筛选了出来

通过上面的讲解,已经能反应出在outer join中的筛选条件在on中和where中的区别,开发人员如能详细了解之中差别,能规避很多在编写sql过程中出现的莫名其妙的错误。
sql连接查询中on筛选与where筛选的区别的更多相关文章
- 【杂记】mysql 左右连接查询中的NULL的数据筛选问题,查询NULL设置默认值,DATE_FORMAT函数
MySQL左右连接查询中的NULL的数据筛选问题 xpression 为 Null,则 IsNull 将返回 True:否则 IsNull 将返回 False. 如果 expression 由多个变量 ...
- sql连接查询中的分类
sql连接查询中的分类 1.内连接(结果不保留表中未对应的数据) 1.1等值连接:关联条件的运算符是用等号来连接的. 1.2不等值连接:连接条件是出等号之外的操作符 1.3自然连接:特殊的等值连接,在 ...
- MySQL左右连接查询中的NULL的数据筛选问题
这里使用左连接为例子,对于左连接是将左边表的数据显示,右边表中如果没有对应的数据则使用null填充. game表: game_type表: SELECT g.name,g.type_id,t.type ...
- 连接查询中on and和on where的区别
一.区别 1. and条件是在生成临时表时使用的条件,它不管and中的条件是否为真,都会返回左(或者右)边表中的记录. 2.where条件是在临时表生成好后,再对临时表进行过滤的条件.这时已经没有le ...
- 关于连接查询主要是左右连接查询中,where和on的区别
工作中,今天用到左连接查询,我自己造的数据,需要根据条件进行筛选,但是筛选不符合我的要求,最终发现是左右连接中where和on的区别,在作怪,工作中用的表关联太多,我下面简化要点,仅仅把注意点写个简单 ...
- SQL Server查询中对于单列数据','分割的数据进行的拆分操作,集合的每一个行变多行
1.cross apply cross apply 我们可以把它看作成是inner join 来使用 2.outer apply outer apply我们可以把它看做是left join 来使用 注 ...
- SQL Server连接查询之Cross Apply和Outer Apply的区别及用法(转载)
先简单了解下cross apply的语法以及会产生什么样的结果集吧!示例表: SELECT * FROM tableA CROSS APPLY tableB 两张表直接连接,不需要任何的关联条件,产生 ...
- sql连接查询(inner join、full join、left join、 right join)
sql连接查询(inner join.full join.left join. right join) 一.内连接(inner join) 首先我这有两张表 1.顾客信息表customer 2.消费订 ...
- SQLServer SQL连接查询深度探险(摘录
SQL连接查询深度探险[摘录] 测试环境: Windows XP Profession MySQL 5.0.45 Oracle 9i DB2 UDB 9.1 测试的SQL脚本如下:此脚本适合MySQL ...
随机推荐
- Troubleshooting OpenStack 瘫痪 - 每天5分钟玩转 OpenStack(160)
这是 OpenStack 实施经验分享系列的第 10 篇.是软件就会有 bug,OpenStack 也不例外,只要用它就一定会遇到故障.Troubleshooting(故障排除)是运维 OpenSta ...
- 自定义分页Gridview中Excel导出
先上图,如图所示导出所有查询出的数据 用的是AspNetPager分页控件,这个导出方法,不受分页和gridview列中数据的约束,可以导出您想导出的数据 首先前台页面代码,lblink即为导出exc ...
- iOS实现视频和图片的上传
关于iOS如何实现视频和图片的上传, 我们先理清下思路 思路: #1. 如何获取图片? #2. 如何获取视频? #3. 如何把图片存到缓存路径中? #4. 如何把视频存到缓存路径中? #5. 如何上传 ...
- div 宽高相等2种实现方式
div.wh{ background:#ff0;width:50%;position:relative;display:inline-block; } div.wh:before{ content: ...
- 1588: [HNOI2002]营业额统计
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 9203 Solved: 3097[Submit][Stat ...
- CAEmitterLayer 粒子效果(发射器)
//创建Layer CAEmitterLayer *emitterLayer = [CAEmitterLayer layer]; //边框 emitterLayer.borderWidth = 1.0 ...
- python 接口自动化测试(三)
1.WriteIni.py import ConfigParser cf = ConfigParser.ConfigParser() cf.add_section("PC_WSDL" ...
- Android OkHttp使用与分析
安卓开发领域,很多重要的问题都有了很好的开源解决方案,例如网络请求 OkHttp + Retrofit 简直就是不二之选."我们不重复造轮子不表示我们不需要知道轮子该怎么造及如何更好的造!& ...
- tomcat文件夹没有部署项目和Tomcat中webapps中没有运行项目-上传下载文件和图片
1.eclipse不像MyEclipse默认将项目部署到tomcat安装目录下的webapps中,而默认部署到工作目录下的.metadata.plugins\org.eclipse.wst.serve ...
- Linux文件权限rwx简单了解
Ⅰ 了解Linux下的文件权限 如上图所示,ll命令详细展示当前目录下的文件或者子目录信息 红框标注的即为此文件或者目录的权限 [第一行文件10.c的权限以-开头,用来说明这是一个文件:第四行cod ...