有这样的一个问题:查询使用mysql中left(right)join筛选条件在on与where查询出的数据是否有差异。

可能只看着两个关键字看不出任何的问题。那我们使用实际的例子来说到底有没有差异。

例如存在两张表结构

表结构1

Sql代码

DROP TABLE IF EXISTS `A`;

CREATE TABLE `A` (

`ID` INT(11) NOT NULL,

PRIMARY KEY (`ID`)

) ENGINE=MYISAM DEFAULT CHARSET=utf8

表结构2

Sql代码

DROP TABLE IF EXISTS `A`;

CREATE TABLE `A` (

`ID` INT(11) NOT NULL,

PRIMARY KEY (`ID`)

) ENGINE=MYISAM DEFAULT CHARSET=utf8

表一插入数据

Sql代码

INSERT INTO `A`(id)VALUES(1);

INSERT INTO `A`(id)VALUES(2);

INSERT INTO `A`(id)VALUES(3);

INSERT INTO `A`(id)VALUES(4);

INSERT INTO `A`(id)VALUES(5);

INSERT INTO `A`(id)VALUES(6);

表二插入数据

Sql代码

INSERT INTO `B`(id)VALUES(1);

INSERT INTO `B`(id)VALUES(2);

INSERT INTO `B`(id)VALUES(3);

完成后A,B表数据如下:

语句一

Sql代码

SELECT A.ID AS AID,B.ID AS BID FROM A LEFT JOIN B ON A.ID = B.ID WHERE B.ID <3

语句二

Sql代码

SELECT A.ID AS AID,B.ID AS BID FROM A LEFT JOIN B ON A.ID = B.ID AND B.ID <3

以上两个语句的查询结果是否一致。

我没有注意到这两个查询存在任何差异的【以前也没这么写过sql】。

我们看看实际结果

语句一的查询结果

语句二的查询结果为:

发现两个查询存在差异。

为什么会存在差异,这和on与where查询顺序有关。

我们知道标准查询关键字执行顺序为 from->where->group by->having->order by

left join 是在from范围类所以 先on条件筛选表,然后两表再做left join。

而对于where来说在left join结果再次筛选。

第一sql语句:

SELECT A.ID AS AID,B.ID AS BID FROM A LEFT JOIN B ON A.ID = B.ID WHERE B.ID <3

查询过程如下等价于:

1:先是left join

Sql代码

SELECT A.ID AS AID,B.ID AS BID FROM A LEFT JOIN B ON A.ID = B.ID

查询结果如下

2:再查询结果中将B.ID即BID<2筛选出来。

所以查询结果为:

这里可以理解执行过程为:

(1).A表和B表产生笛卡尔积

SELECT A.ID AS AID,B.ID AS BID FROM A JOIN B

(2).然后笛卡尔积的结果集通过条件on进行筛选后留下三条记录

SELECT A.ID AS AID,B.ID AS BID FROM A JOIN B ON A.ID = B.ID

(3).结果集通过left join和A表进行左连接:

SELECT A.ID AS AID,B.ID AS BID FROM A LEFT JOIN B ON A.ID = B.ID

(4).最后左连接后的结果通过where条件进行过滤:

SELECT A.ID AS AID,B.ID AS BID FROM (A LEFT JOIN B ON A.ID = B.ID) WHERE B.ID <3

第二sql语句:

SELECT A.ID AS AID,B.ID AS BID FROM A LEFT JOIN B ON A.ID = B.ID AND B.ID <3

查询过程如下等价于:

1:先按照on条件刷选表等价于先筛选B表:

2:再已上查询结果与A表做left join,这也是为什么我们看到第二个查询的sql会保留A表的原因。

所以查询结果为:

执行过程为:

(1).首先两表笛卡尔积:

SELECT A.ID AS AID,B.ID AS BID FROM A JOIN B

(2).对笛卡尔积进行on(ON (A.ID = B.ID AND B.ID <3))条件过滤:

SELECT A.ID AS AID,B.ID AS BID FROM A JOIN B ON (A.ID = B.ID AND B.ID <3)

(3).最后对过滤后的结果和A表进行左连接(LEFT JOIN):

所以结果为:

ON与where的使用一定要注意场所:

(1):ON后面的筛选条件主要是针对的是关联表【而对于主表刷选条件不适用】。

例如

Sql代码

SELECT A.ID AS AID,B.ID AS BID FROM A LEFT JOIN B ON A.ID = B.ID AND A.ID =3

这个的查询结果为

挺诧异的吧和我们期望的结果不一样,并为筛选出AID=3的数据。

但是我们也发现 AID 与 中AID 1 于2对应的值为NULL,关联表只取了满足A表筛刷选条件的值。

查询过程为:

(1).A表和B表笛卡尔积:

SELECT A.ID AS AID,B.ID AS BID FROM A JOIN B

(2)笛卡尔积后进行on条件过滤:

SELECT A.ID AS AID,B.ID AS BID FROM A JOIN B ON A.ID = B.ID AND A.ID =3

(3)过滤后的结果集和A表再左连接(LEFT JOIN):

所以结果为:

总结:

( 1 )   :主表条件在on后面时附表只取满足主表帅选条件的值、而主表还是取整表。

(2):对于主表的筛选条件应放在where后面,不应该放在ON后面

(3):对于关联表我们要区分对待。如果是要条件查询后才连接应该把查询件

放置于ON后。

如果是想再连接完毕后才筛选就应把条件放置于where后面

(4): 对于关联表我们其实可以先做子查询再做join

所以第二个sql等价于

Sql代码

SELECT A.ID AS AID, B1.ID AS BID

FROM A LEFT JOIN ( SELECT B.ID FROM B WHERE B.ID <3 )B1 ON A.ID = B1.ID

以上全在mysql5.6上测试过

mysql right关键字_MYSQL 中的LEFT( RIGHT ) JOIN使用ON 与WHERE 筛选的差异相关推荐

  1. mysql escape关键字_MySQL中ESCAPE关键字的用法详解

    MySQL转义 转义即表示转义字符原来的语义,一个转义字符的目的是开始一个字符序列,使得转义字符开头的该字符序列具有不同于该字符序列单独出现时的语义. MySQL中,转义字符以"\" ...

  2. 判断mysql的关键字_mysql中查询常用的关键字

    最简单的查询: 这里需要注意的是where子句中条件过滤使用到的关键字,比如用到逻辑运算符like中的'%'(匹配一个或多个字符)和'_'(仅匹配一个)等. distinct关键字 这个关键字,主要用 ...

  3. MYSQL 中的LEFT( RIGHT ) JOIN使用ON 与WHERE 筛选的差异

    2019独角兽企业重金招聘Python工程师标准>>> 有这样的一个问题:查询使用mysql中left(right)join筛选条件在on与where查询出的数据是否有差异. 可能只 ...

  4. mysql where关键字_MySQL WHERE 子句

    我们知道从 MySQL 表中使用 SQL SELECT 语句来读取数据. 如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句中. 语法 以下是 SQL SELECT 语句使用 ...

  5. mysql range用法_MySQL中Explain的用法总结(详细)

    本篇文章给大家带来的内容是关于MySQL中Explain的用法总结(详细),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 执行计划(query Execution plan) 语法e ...

  6. explain mysql怎么用_mysql中explain用法详解

    EXPLAIN用于SELECT语句中的每个表返回一行信息.表以它们在处理查询过程中将被MySQL读入的顺序被列出 如果在select语句前放上关键词explain,mysql将解释它如何处理selec ...

  7. mysql提取数字_Mysql中实现提取字符串中的数字的自定义函数分享

    因需要在mysql的数据表中某一字符串中的字段提取出数字,在网上找了一通,终于找到了一个可用的mysql函数,可以有效的从字符串中提取出数字. 该mysql提取出字符串中的数字函数如下: 复制代码 代 ...

  8. mysql 关联索引_mysql中关于关联索引的问题——对a,b,c三个字段建立联合索引,那么查询时使用其中的2个作为查询条件,是否还会走索引?...

    情况描述:在MySQL的user表中,对a,b,c三个字段建立联合索引,那么查询时使用其中的2个作为查询条件,是否还会走索引? 根据查询字段的位置不同来决定,如查询a,     a,b    a,b, ...

  9. mysql getnum函数_Mysql中实现提取字符串中的数字的自定义函数分享

    因需要在MysqL的数据表中某一字符串中的字段提取出数字,在网上找了一通,终于找到了一个可用的MysqL函数,可以有效的从字符串中提取出数字. 该MysqL提取出字符串中的数字函数如下: CREATE ...

最新文章

  1. JS中IE与W3C不同的地方
  2. Learun FrameWork 强大工作流引擎,让OA更智能
  3. PowerShell CLI 获取VM信息
  4. 在线实时大数据平台Storm开发之wordcount
  5. 病毒行为分析初探(三)
  6. ElasticSearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解...
  7. 敏捷开发生态系统系列之三:计划跟踪II(需求优先级排序-迭代期内无变更-团队承诺)...
  8. wpf 界面加载 Command
  9. Centos6.5搭建mongodb分片
  10. 天津市高分二号卫星影像获取/高分一号卫星影像
  11. 019--python内置函数
  12. STP的BPDU报文类型
  13. CSTC2021 WriteUp
  14. Matlab:数值积分与符号计算
  15. 数据如何变成知识(3):提取暗数据
  16. 计算机试题上网部分怎么做,考试经验之谈:计算机一级考试上网题怎么操作?...
  17. 带你玩转CSS浏览器兼容问题——囊括了目前我所有已知的兼容性问题
  18. PhysX官方手册翻译(二)
  19. Android视频录制--屏幕录制
  20. 物联网工程-hadoop论文

热门文章

  1. Qgis的下载安装(Qgis3.16.12)
  2. 怎么python画好几朵玫瑰花_使用Python画玫瑰花
  3. 喜茶多肉瓜瓜 | 埃德珈奶茶饮品培训,饮品配方做法制作教程
  4. 如何在mac版chrome安装第三方插件
  5. Mac下添加Chrome插件
  6. [乐意黎转载]从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式
  7. 虚拟机屏幕自适应问题
  8. 廖老师的Python教程——Python简介
  9. Linux之安全最佳做法(未完成)
  10. Ls-Dyna对预应力钢筋混凝土结构的抗爆模拟