今天在工作的时候碰到了一个问题,A表B表left join后在on后面关于A表的条件过滤语句没起到我想要的过滤作用,还是对左连接等理解的不够呀。

SELECT * FROM student;
SELECT * FROM class;
以下是两张表的查询结果:

        

      student表                    class表

                

  先来看一下student表和class表根据cla_id左连接返回的结果

SELECT * FROM student stu
LEFT JOIN class cla
ON stu.cla_id = cla.cla_id
返回的结果也正如我的预期,那么就再来看看加上一个stu_id=1条件后返回的结果
SELECT * FROM student stu
LEFT JOIN class cla
ON stu.cla_id = cla.cla_id
AND stu.stu_id=1
  我当时怎么也想不明白,天怎么会返回四条记录,我不是在后面加了个stu_id=1的条件吗?不是过滤了student表应该只返回第一条数据吗?当时听一些人说不管on后面跟什么条件,
左表的数据会全部查出来,因此要想过滤需要把条件放到where后面比如把SQL改成这样:
SELECT * FROM student stu
LEFT JOIN class cla
ON stu.cla_id = cla.cla_id
WHERE stu.stu_id=1
  那么on和where的区别就在于:
  on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录,而where条件是在临时表生成好后,再对临时表进行过滤的条件。而且除了stu_id=1的
那条记录,class表中字段不满足过滤条件的记录(即使被关联到了)全是NULL,所以on后面的语句最好只写两个表相关联的语句,并不能做单方面的过滤。也可以这么简单的理解,以坐标
为主,先查询出左表的全部记录,然后关联右表,将符合条件的记录的数据填充进查询出来的结果。right join 和 full join 具有相同的特性,但是inner join不同,它可以在on 那
里做过滤处理,也就是说放在on后面和where后面作用是一样的。
  
  顺便提一下,当我们对一个字段进行了处理重命名后,就直接在where语句后面用做过滤条件的话,会报不能识别的列。下面我以mysql的方言为例。
  SELECT id, begintime, from_unixtime((UNIX_TIMESTAMP(begintime)*1000+auctiontime)/1000) AS endtime FROM auctioncommendity where endtime>NOW();
 这条语句会提示endtime是不能识别的列,要在这个查询作为一个结果集在外围where条件做过滤才可行,例如这样:
  select a.* from (SELECT id, begintime, from_unixtime((UNIX_TIMESTAMP(begintime)*1000+auctiontime)/1000) AS endtime FROM auctioncommendity ) a
where endtime>NOW();
  但是又有些情况下是可以的,比如order by 和group后在having后面做过滤不需要用到子查询就可以直接使用经过处理的重命名字段。关于原因....先睡觉,以后再找
  
  话说写博客可真花时间呀.....

LEFT JOIN、Right、Full后ON和WHERE的区别的更多相关文章

  1. left join on 后and 和 where 的区别

    SELECT * FROM student a LEFT JOIN sc b ON a.Sid = b.Sid AND a.Sname="赵雷" 结果:(left join 左连接 ...

  2. mysql中join后on、where的区别

    SELECT * FROM A; SELECT * FROM B; 以上是两张表的机构 SELECT * FROM A LEFT JOIN B ON A.id=b.a_id ; ; ; 两个语句查询出 ...

  3. mysql left join中on后加条件判断和where中加条件的区别

    left join中关于where和on条件的几个知识点: .多表left join是会生成一张临时表,并返回给用户 .where条件是针对最后生成的这张临时表进行过滤,过滤掉不符合where条件的记 ...

  4. MySQL left join操作中 on与where放置条件的区别

    优先级 两者放置相同条件,之所以可能会导致结果集不同,就是因为优先级.on的优先级是高于where的. 1 1 首先明确两个概念: LEFT JOIN 关键字会从左表 (table_name1) 那里 ...

  5. sleep、yield、join方法简介与用法 sleep与wait区别 多线程中篇(十五)

    Object中的wait.notify.notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁( ...

  6. java中sleep和join和yield和wait和notify的区别

    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...

  7. MySQL的join on和 where 的执行顺序和区别,以及各种连接说明

    目录 1.各种连接的解读说明: 1.1.各种连接的含义和说明 1.1.1 所有连接分类 1.1.2 left join 和 left outer join 区别 1.2.神图参考 1.4.一些参考说明 ...

  8. [Reprint]C++函数前和函数后加const修饰符区别

    c++中关于const的用法有很多,const既可以修饰变量,也可以函数,不同的环境下,是有不同的含义.今天来讲讲const加在函数前和函数后面的区别.比如: 01 #include<iostr ...

  9. C++函数前和函数后加const修饰符区别

    class Test(){ public: Test(){} const int foo(int a); const int foo(int a) const; }; 一.概念 当const在函数名前 ...

随机推荐

  1. 在当前iframe中, 获取Iframe的id

    window.frameElement   返回嵌入当前window对象的元素(比如 <iframe> 或者 <object>),如果当前window对象已经是顶层窗口,则返回 ...

  2. 为了让vi命令也可以使用vim的配置,需要修改 vi /etc/bashrc 增加一行 alias vi='vim'此时,经过上面配置已经可以显示语法高亮了

    为了让vi命令也可以使用vim的配置,需要修改 vi /etc/bashrc 增加一行 aliasvi='vim'此时,经过上面配置已经可以显示语法高亮了

  3. 深入理解python之self

    首先明确的是self只有在类的方法中才会有,独立的函数或方法是不必带有self的.self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数. self名称不是必须的,在python中self ...

  4. Performance tips

    HTML5 Techniques for Optimizing Mobile Performance Scrolling Performance layout-performance

  5. DB2 的create or update方法

    通过merge方法实现的: MERGE INTO IFEBASE.STYLE AS MT USING (SELECT :scenario AS SCENARIO_ID, :style AS SHAPE ...

  6. 从3D Studio Max导入物体 Importing Objects From 3D Studio Max

    原地址:http://game.ceeger.com/Manual/HOWTO-ImportObjectMax.html If you make your 3D objects in 3dsMax, ...

  7. Openstack os-networks API create network 方法

    官方文档在请求方法和地址上有错误: http://api.openstack.org/api-ref.html#ext-os-networks 正确的地址为: /v2/{tenant_id}/os-n ...

  8. mysql 事务提交过程

     打开binlog选项后,执行事务提交命令时,就会进入两阶段提交模式.两阶段提交分为prepare阶段和commit两个阶段.流程如下 :这里面涉及到两个重要的参数:innodb_flush_log_ ...

  9. HDU 3255 Farming (线段树+扫面线,求体积并)

    题意:在一块地上种蔬菜,每种蔬菜有个价值.对于同一块地蔬菜价值高的一定是最后存活,求最后的蔬菜总值. 思路:将蔬菜的价值看做高度的话,题目就转化成求体积并,这样就容易了. 与HDU 3642 Get ...

  10. 15.RDD 创建内幕解析

    第15课:RDD创建内幕 RDD的创建方式 Spark应用程序运行过程中,第一个RDD代表了Spark应用程序输入数据的来源,之后通过Trasformation来对RDD进行各种算子的转换,来实现具体 ...