LEFT JOIN、Right、Full后ON和WHERE的区别
今天在工作的时候碰到了一个问题,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的区别的更多相关文章
- left join on 后and 和 where 的区别
SELECT * FROM student a LEFT JOIN sc b ON a.Sid = b.Sid AND a.Sname="赵雷" 结果:(left join 左连接 ...
- mysql中join后on、where的区别
SELECT * FROM A; SELECT * FROM B; 以上是两张表的机构 SELECT * FROM A LEFT JOIN B ON A.id=b.a_id ; ; ; 两个语句查询出 ...
- mysql left join中on后加条件判断和where中加条件的区别
left join中关于where和on条件的几个知识点: .多表left join是会生成一张临时表,并返回给用户 .where条件是针对最后生成的这张临时表进行过滤,过滤掉不符合where条件的记 ...
- MySQL left join操作中 on与where放置条件的区别
优先级 两者放置相同条件,之所以可能会导致结果集不同,就是因为优先级.on的优先级是高于where的. 1 1 首先明确两个概念: LEFT JOIN 关键字会从左表 (table_name1) 那里 ...
- sleep、yield、join方法简介与用法 sleep与wait区别 多线程中篇(十五)
Object中的wait.notify.notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁( ...
- java中sleep和join和yield和wait和notify的区别
1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...
- MySQL的join on和 where 的执行顺序和区别,以及各种连接说明
目录 1.各种连接的解读说明: 1.1.各种连接的含义和说明 1.1.1 所有连接分类 1.1.2 left join 和 left outer join 区别 1.2.神图参考 1.4.一些参考说明 ...
- [Reprint]C++函数前和函数后加const修饰符区别
c++中关于const的用法有很多,const既可以修饰变量,也可以函数,不同的环境下,是有不同的含义.今天来讲讲const加在函数前和函数后面的区别.比如: 01 #include<iostr ...
- C++函数前和函数后加const修饰符区别
class Test(){ public: Test(){} const int foo(int a); const int foo(int a) const; }; 一.概念 当const在函数名前 ...
随机推荐
- 也可以使用如下命令更改您的默认 Shell
也可以使用如下命令更改您的默认 Shell chsh -s /bin/zsh (需要输入您的密码)
- Nginx搭建flv视频点播服务器
Nginx搭建flv视频点播服务器 前一段时间使用Nginx搭建的多媒体服务器只能在缓冲过的时间区域内拖放, 而不能拖放到未缓冲的地方. 这就带来了一个问题: 如果视频限速的速率很小, 那么客户端观看 ...
- 利用Openvswitch实现不同物理机中的Docker容器互连
1. 测试环境 75机(10.11.150.75):Red Hat Enterprise Linux Server 7.0,无外网访问权限,已安装Docker Server 74机(10.11.150 ...
- HDU 4588 Count The Carries(找规律,模拟)
题目 大意: 求二进制的a加到b的进位数. 思路: 列出前几个2进制,找规律模拟. #include <stdio.h> #include <iostream> #includ ...
- iOS第三方解决键盘遮挡-IQKeyboardManager
百度云:http://pan.baidu.com/s/1yg5ae githun:https://github.com/hackiftekhar/IQKeyboardManager AppDelega ...
- POJ 1401
#include<iostream>using namespace std;int main(){ int num; int i; int sum; cin> ...
- .bash_profile和.bashrc的区别(如何设置生效)
/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/etc/profile.d目录的配置文件中搜集shell的设置. /etc/bashrc:为每一个 ...
- C# 中Newtonsoft.Json的安装和使用
官网参考:http://json.codeplex.com/ 在程序包管理控制台,键入NuGet命令 install-package Newtonsoft.Json 安装Newtonsoft.Js ...
- MySQL 数据库存储引擎
简单介绍 存储引擎就是指表的类型.数据库的存储引擎决定了表在计算机中的存储方式.存储引擎的概念是MySQl的特点,而且是一个插入式的存储引擎概念.这就决定了MySQl数据库中的表可以使用不同的存储方式 ...
- C#获取根目录的方法集合
1.取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径 方法2.AppDomain.Curren ...