解析mysql left( right ) join使用on与where筛选的差异


Posted in PHP onJune 18, 2013

有这样的一个问题mysql查询使用mysql中left(right)join筛选条件在on与where查询出的数据是否有差异。
可能只看着两个关键字看不出任何的问题。那我们使用实际的例子来说到底有没有差异。

例如存在两张表结构
表结构1

drop table if EXISTS A;  
CREATE TABLE A (  
  ID int(1) NOT NULL,  
  PRIMARY KEY  (ID)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

表结构2
drop table if EXISTS B;  
CREATE TABLE B (  
  ID int(1) NOT NULL,  
  PRIMARY KEY  (ID)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

表一插入数据
insert into A values ( 1 );  
insert into A values ( 2 );  
insert into A values ( 3 );  
insert into A values ( 4 );  
insert into A values ( 5 );  
insert into A values ( 6 ); 

表二插入数据
insert into B values ( 1 );  
insert into B values ( 2 );  
insert into B values ( 3 ); 

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

解析mysql left( right ) join使用on与where筛选的差异


语句一

select  A.ID as AID, B.ID as BID   from A left join B on A.ID = B.ID where B.ID<3

语句二
select  A.ID as AID, B.ID as BID  from A left join B on A.ID = B.ID and  B.ID<3 

以上两个语句的查询结果是否一致。
反正一切我是没有注意到这两个查询存在任何差异的【以前也没这么写过sql】。
我们看看实际结果
语句一的查询结果

解析mysql left( right ) join使用on与where筛选的差异

 

语句二的查询结果为:

 

解析mysql left( right ) join使用on与where筛选的差异

 

发现两个查询存在差异。

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

我们知道标准查询关键字执行顺序为 from->where->group by->having->order by[ 记得不是很清楚呢]

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

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

第一sql语句查询过程如下等价于:
1:先是left join

select  A.ID as AID, B.ID as BID   from A left join B on A.ID = B.ID 

查询结果如下

  解析mysql left( right ) join使用on与where筛选的差异

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

也就是我们上面看到的结果。

第二sql语句查询过程如下等价于:

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

   解析mysql left( right ) join使用on与where筛选的差异

2:再已上查询结果与A表做left join,这也是为什么我们看到第二个查询的sql会保留A表的原因。
ON与where的使用一定要注意场所:
(1):ON后面的筛选条件主要是针对的是关联表【而对于主表刷选条件不适用】。
例如

select  A.ID as AID, B.ID as BID from A left join B on A.ID = B.ID and A.ID = 3 

这个的查询结果为

解析mysql left( right ) join使用on与where筛选的差异

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

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

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

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

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

              放置于ON后。

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

 (4): 对于关联表我们其实可以先做子查询再做join
所以第二个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.1上测试过
PHP 相关文章推荐
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
Mar 15 PHP
解析在apache里面给php写虚拟目录的详细方法
Jun 24 PHP
关于PHP自动判断字符集并转码的详解
Jun 26 PHP
PHP使用Mysql事务实例解析
Sep 08 PHP
Apache启动报错No space left on device: AH00023该怎么解决
Oct 16 PHP
PHP面向对象详解(三)
Dec 07 PHP
Laravel最佳分割路由文件(routes.php)的方式
Aug 04 PHP
总结PHP中DateTime的常用方法
Aug 11 PHP
php_pdo 预处理语句详解
Nov 21 PHP
关于php几种字符串连接的效率比较(详解)
Feb 22 PHP
PHP微信PC二维码登陆的实现思路
Jul 13 PHP
CentOS7系统搭建LAMP及更新PHP版本操作详解
Mar 26 PHP
ubuntu下编译安装xcache for php5.3 的具体操作步骤
Jun 18 #PHP
编译php 5.2.14+fpm+memcached(具体操作详解)
Jun 18 #PHP
解析PHP实现多进程并行执行脚本
Jun 18 #PHP
PHP实现多进程并行操作的详解(可做守护进程)
Jun 18 #PHP
解析php中static,const与define的使用区别
Jun 18 #PHP
解析htaccess伪静态的规则
Jun 18 #PHP
解析php中const与define的应用区别
Jun 18 #PHP
You might like
虚拟主机中对PHP的特殊设置
2006/10/09 PHP
PHP中数组的三种排序方法分享
2012/05/07 PHP
PHP数组无限分级数据的层级化处理代码
2012/12/29 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
Javascript-Mozilla和IE中的一个函数直接量的问题
2007/01/09 Javascript
基于jquery的tab切换 js原理
2010/04/01 Javascript
jquery插件制作 自增长输入框实现代码
2012/08/17 jQuery
jquery 页面滚动到指定DIV实现代码
2013/09/25 Javascript
JavaScript中的lastIndexOf()方法使用详解
2015/06/06 Javascript
JQuery实现鼠标滚轮滑动到页面节点
2015/07/28 Javascript
浅析四种常见的Javascript声明循环变量的书写方式
2015/10/14 Javascript
详解nodeJS之二进制buffer对象
2017/06/03 NodeJs
浅谈JS获取元素的N种方法及其动静态讨论
2017/08/25 Javascript
vue中的scope使用详解
2017/10/29 Javascript
vue.js 使用axios实现下载功能的示例
2018/03/05 Javascript
利用Node.js批量抓取高清妹子图片实例教程
2018/08/02 Javascript
微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】
2019/02/20 Javascript
微信小程序中weui用法解析
2019/10/21 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
2019/11/04 Javascript
使用vue实现HTML页面生成图片的方法
2020/03/12 Javascript
vuex管理状态仓库使用详解
2020/07/29 Javascript
详解JavaScript之Array.reduce源码解读
2020/11/01 Javascript
[01:34]2014DOTA2 TI预选赛预选赛 选手比赛房大揭秘!
2014/05/20 DOTA
python实现指定文件夹下的指定文件移动到指定位置
2018/09/17 Python
pyinstaller还原python代码过程图解
2020/01/08 Python
Python运行异常管理解决方案
2020/03/09 Python
Python3之外部文件调用Django程序操作model等文件实现方式
2020/04/07 Python
TripAdvisor台湾:全球最大旅游网站
2018/08/26 全球购物
荷兰在线啤酒店:Beerwulf
2019/08/26 全球购物
地球鞋加拿大官网:Earth Shoes Canada
2020/11/17 全球购物
入党积极分子十八届四中全会思想汇报
2014/10/23 职场文书
2015年初一班主任工作总结
2015/05/13 职场文书
2015年生产部工作总结范文
2015/05/25 职场文书
力克胡哲观后感
2015/06/10 职场文书
记者节感言
2015/08/03 职场文书
mybatis中sql语句CDATA标签的用法说明
2021/06/30 Java/Android