设为首页 收藏本站
查看: 717|回复: 0

[经验分享] mysql left( right ) join使用on 与where 筛选的差异

[复制链接]

尚未签到

发表于 2016-10-23 10:50:31 | 显示全部楼层 |阅读模式
  有这样的一个问题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表数据如下:
DSC0000.jpg

  语句一

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】。
  我们看看实际结果
  语句一的查询结果
  
DSC0001.jpg

  
  语句二的查询结果为:
  
DSC0002.jpg

 

发现两个查询存在差异。

为什么会存在差异,这和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
  查询结果如下
DSC0003.jpg
  2:再查询结果中将B.ID即BID<2筛选出来。

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

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

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

   DSC0004.jpg

   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
  这个的查询结果为
DSC0005.jpg
挺诧异的吧和我们期望的结果不一样,并为筛选出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上测试过
  
 

 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-290189-1-1.html 上篇帖子: Access转出到Mysql,咱自己动手丰衣足食.. -- 纯JS代码 下篇帖子: (转)MySQL的经典用法(三)----海量数据统计处理,模拟物化视图
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表