sql连接查询中on筛选与where筛选的区别

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

时间: 2024-10-21 05:11:36

sql连接查询中on筛选与where筛选的区别的相关文章

sql连接查询中的分类

sql连接查询中的分类 1.内连接(不留null) 1.1等值连接:关联条件的运算符是用等号来连接的. 1.2不等值连接:连接条件是出等号之外的操作符 1.3自然连接:特殊的等值连接,在同样的字段名存在的情况下,比较数据值是不是相等. 2.外连接(留null) 2.1左连接:以左表为准,即使右边没有满足连接条件对应的记录,左边也会出现在查询结果中,右边以空值出现. 2.2右连接:以右表为准,即使右边没有满足连接条件对应的记录,右边也会出现在查询结果中,左边以空值出现. 2.3全外连接:都可以出现

MySQL左右连接查询中的NULL的数据筛选问题

原文地址:https://www.cnblogs.com/alonely/p/10452448.html

【大数据】SparkSql连接查询中的谓词下推处理(一)

本文首发于 vivo互联网技术 微信公众号 作者:李勇 目录: 1.SparkSql 2.连接查询和连接条件 3.谓词下推 4.内连接查询中的谓词下推规则 4.1.Join后条件通过AND连接 4.2.Join后条件通过OR连接 4.3.分区表使用OR连接过滤条件 1.SparkSql SparkSql 是架构在 Spark 计算框架之上的分布式 Sql 引擎,使用 DataFrame 和 DataSet 承载结构化和半结构化数据来实现数据复杂查询处理,提供的 DSL可以直接使用 scala 语

SQL——连接查询

以mysql为例: 新建两张表table1和table2 CREATE TABLE `table1` ( `id` int(11) NOT NULL auto_increment, `name` varchar(20) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf-8 CREATE TABLE `table2` ( `id` int(11) NOT NULL auto_increment, `name`

SQL Server查询中特殊字符的处理方法

SQL Server查询中,经常会遇到一些特殊字符,比如单引号"'"等,这些字符的处理方法,是SQL Server用户都应该需要知道的. 我们都知道SQL Server查询过程中,单引号"'"是特殊字符,所以在SQL Server查询的时候要转换成双单引号"''".但这只是特殊字符的一个,在实际项目中,发现对于like操作还有以下特殊字符:下划线"_",百分号"%",方括号"[]"以及尖

连接查询的时候,on和where的区别。

使用的是NorthWind数据测试. 1.内部连接.在连接的时候省略了inner.查询客户VINET的订单. select * FROM Orders a join Customers bon a.CustomerID=b.CustomerID AND a.CustomerID='VINET' 返回记录按着VINET进行了过滤. select * FROM Orders a join Customers bon a.CustomerID=b.CustomerIDWHERE a.CustomerI

Sql_连接查询中on筛选与where筛选的区别

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 可以把这两张表看作

sql连接查询

本文主要列举两张和三张表来讲述多表连接查询. 新建两张表: 表1:student  截图如下: 表2:course  截图如下: (此时这样建表只是为了演示连接SQL语句,当然实际开发中我们不会这样建表,实际开发中这两个表会有自己不同的主键.) 一.外连接 外连接可分为:左连接.右连接.完全外连接. 1.左连接  left join 或 left outer join SQL语句:select * from student left join course on student.ID=cours

SQL连接查询、变量、运算符、分支、循环语句

连接查询:通过连接运算符可以实现多个表查询.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 常用的两个链接运算符: 1.join   on 2.union 在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中.当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息.连接操作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型.为不同实体创建新的表,随后通过连接进行查询. 示例一: 示例二: 示例三: 示例四: