sql连接查询语句中on、where筛选的区别总结

发布时间 - 2026-01-11 02:15:36    点击率:

前言

相信对于每位程序员来说,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  # 区别  # sql中on和where的区别  # 解析mysql left( right ) join使用on与where筛选的差异  # MySQL查询条件中放置on和where的区别分析  # 杭州  # 两张  # 那条  # 放在  # 笛卡尔  # 这两种  # 就拿  # 这一步  # 莫名其妙  # 过滤掉  # 有什么  # 是在  # 在这里  # 也会  # 就能  # 也没  # 画蛇添足  # 两种  # 只需  # 这段 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 音乐网站服务器如何优化API响应速度?  Python函数文档自动校验_规范解析【教程】  Java遍历集合的三种方式  javascript日期怎么处理_如何格式化输出  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  如何用美橙互联一键搭建多站合一网站?  如何快速生成高效建站系统源代码?  php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  如何在IIS中新建站点并配置端口与物理路径?  bootstrap日历插件datetimepicker使用方法  如何用IIS7快速搭建并优化网站站点?  如何在万网开始建站?分步指南解析  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  如何选择PHP开源工具快速搭建网站?  HTML 中动态设置元素 name 属性的正确语法详解  如何获取上海专业网站定制建站电话?  如何在宝塔面板中创建新站点?  Android中AutoCompleteTextView自动提示  微信小程序制作网站有哪些,微信小程序需要做网站吗?  Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】  php json中文编码为null的解决办法  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  JavaScript如何实现类型判断_typeof和instanceof有什么区别  JavaScript中如何操作剪贴板_ClipboardAPI怎么用  Laravel API资源类怎么用_Laravel API Resource数据转换  悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】  使用Dockerfile构建java web环境  Laravel如何使用查询构建器?(Query Builder高级用法)  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  轻松掌握MySQL函数中的last_insert_id()  如何安全更换建站之星模板并保留数据?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  高端云建站费用究竟需要多少预算?  如何用JavaScript实现文本编辑器_光标和选区怎么处理  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  如何快速搭建二级域名独立网站?  EditPlus中的正则表达式 实战(1)  创业网站制作流程,创业网站可靠吗?  如何自定义建站之星网站的导航菜单样式?  无锡营销型网站制作公司,无锡网选车牌流程?  如何确保西部建站助手FTP传输的安全性?  三星网站视频制作教程下载,三星w23网页如何全屏?  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  如何快速查询网址的建站时间与历史轨迹?