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过程中出现的莫名其妙的错误。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
HP EVA8400删除VDISK后数据恢复过程分步整理
【故障描述】 某地法院一台HP EVA8400存储,2组扩展柜,物理磁盘由12个1T FATA磁盘(AG691A 454414-001)和10个300G 15K FC磁盘(AG690A 454411-001)组成,LUN数量不确定,主机环境为WINDOWS,存储法院历史案例审理材料。 因本案多方转手,所以我们也无法直接得知故障原因。 【初检及分析】 1、电话初检,确定得知,数据出现故障后再未重用。通常按HP-EVA的故障可能推断,数据恢复的可靠性较高。 2、EVA主机及扩展柜正常关机,之后将所有硬盘标好位置序号,拿出。在数据成功恢复之前,不再开启EVA 8400控制器。 3、接手磁盘后,按如下链路对磁盘进行连接。 4、进入WINDOWS环境,用WINHEX查看磁盘情况,发现所有磁盘均可正常识别。 5、查看每个磁盘信息,发现300G FC磁盘存在PV HEAD,而1T FATA磁盘上均无PV HEAD。查看300G磁盘中存储的Metadata,发现仅描述了一个RSS组组成的LUN,大小不足2T,成员为所有300G磁盘。而1T FATA磁盘中残留的LUN信息则至少包括5...
- 下一篇
记一次服务器宕机处理过程
今天整理之前的运维资料,发现了自己整理的一次刀片服务器(运行的vmware虚拟化)事故处理流程,所以记录下,备忘。 一、事件处理过程 14:10接到机房运维工程师通知,Opmanager监控系统上出现了多台服务器宕机现象,并且均为虚拟机。 14:12通知机房运维工程师检查HP刀片服务器是否有告警,远程登录vcenter进行检查。远程查看发现ESX04(10.203.11.64)出现告警,告警信息如下图所示: 14:15通知工程师ESX04出现告警,然后确认该刀片服务器是否存活,并进入机房确认设备上是否有硬件上的告警。 14:16检查逻辑上的网络接口是否存在异常 如下图所示,发现有两块网卡处于离线状态 14:18检查其它刀片,发现ESXI02对应的网卡,发现为正常的 14:20登录HP刀片管理控制台查看,未发现服务器告警信息。 14:19 参照其它EXSI,尝试更改vmnic6、vmnic7两块网卡模式,该操作无法生效 更改网卡模式无法生效 14:27在ESX04进行手动迁移虚拟机到其他主机上,迁移失败。 14:58 将ESX04主机上的虚拟机全部关机 15:20 重启ESXI主机,HA...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS7,CentOS8安装Elasticsearch6.8.6