SQL左连接中的on and和on where的区别

article/2025/9/23 12:27:31

转载,原文链接:http://blog.csdn.net/xingzhemoluo/article/details/39677891

SQL左右连接中的on and和on where的区别

使用left join时,on and和on where条件的区别如下:
1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录(涉及右表的会直接过滤掉,涉及左右表之间的条件过滤完之后,不符合的左表的记录都会返回同时右表置空)。
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉,on后的条件用来生成左右表关联的临时表,where后的条件对临时表中的记录进行过滤。

实践是检验真理的唯一标准,接下来用实验来证明一下:

先上表结构以及数据:

SQL> create table A (id int, type int);
SQL> select * from A;
ID TYPE


     1          12          13          2

SQL> create table B(id int ,class int);
SQL> select * from B;

    ID      CLASS

     1          12          2

SQL> select * from A left join B on A.id = B.id where A.type = 1;

    ID       TYPE         ID      CLASS

     1          1          1          12          1          2          2

根据上面那段话的解释,where字句是在生成临时表以后再进行过滤的,也就是可以理解为就是一个左连接:select * from A left join B on A.id = B.id;
其运行结果如下:

SQL> select * from A left join B on A.id = b.id;

    ID       TYPE         ID      CLASS

     1          1          1          12          1          2          23          2

然后加上where A.type = 1对临时表进行过滤,除掉A.type不为1的,显然结果正确。


SQL> select * from A left join B on A.id = B.id and A.type = 1;

    ID       TYPE         ID      CLASS

     1          1          1          12          1          2          23          2

因为左连接不管on and语句是否为真都必须返回左表所有的记录,所以and A.type=1;没有起到任何作用。


SQL> select * from A left join B on A.id = B.id and B.class = 1;

    ID       TYPE         ID      CLASS

     1          1          1          13          22          1

根据上面那段话的解释:on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。显然左连接再加上新的条件:B.class = 1筛选掉第二行记录,结果正确。

SQL> select * from A left join B on A.id = B.id where B.class = 1;

    ID       TYPE         ID      CLASS

     1          1          1          1

原因通①。(①,②)和(③,④)就是关键词on and和on where的区别,但结果却完全不同。综上三个例子, where是生成临时表以后再进行过滤,对左右表都进行筛选。而and后面的语句如果是对left join中的左表进行过滤将不起任何作用,对右表进行过滤的话,那么左表还是返回所有行,只是右表会被过滤掉一部分行。

再来看看内连接inner join on and和 on where的区别:

由于刚开始表的数据不是太适合,所以先稍微更新一下,这样更好观察inner join和left join在and和where的不同之处。

SQL> update A set type = 2 where id = 1;

已更新 1 行。

SQL> select * from A;

    ID       TYPE

     1          22          13          2

SQL> select * from B;

    ID      CLASS

     1          12          2

先看看and的:

SQL> select * from A inner join B on A.id = B.id and A.type = 1;

    ID       TYPE         ID      CLASS

     2          1          2          2

显然输出结果与左连接的不一样,先与没有and的内连接比较一下:
SQL> select * from A inner join B on A.id = B.id;

    ID       TYPE         ID      CLASS

     1          2          1          12          1          2          2

显然如果按左连接的逻辑,这个结果就是错误的。但这是Oracle输出的,而不是我瞎打的,显然在内连接时与左连接不同了。这里on and条件和on where条件一样对生成以后的临时表同样会被过滤。显然A表id为1的type不为1,所以它被过滤了。

再上几组来验证一下上面这个猜想是否是正确的:

再来看看内连接的where:
SQL> select * from A inner join B on A.id = B.id where A.type = 1;

    ID       TYPE         ID      CLASS

     2          1          2          2

这个也是和左连接一样生成临时表然后进行过滤,不作解释。

SQL> select * from A inner join B on A.id = B.id and B.class = 1;

    ID       TYPE         ID      CLASS

     1          2          1          1


SQL> select * from A inner join B on A.id = B.id where B.class = 1;

    ID       TYPE         ID      CLASS

     1          2          1          1

对比发现:(⑤,⑥)和(⑦,⑧)结果都一样,也就是说内连接inner join on and 或者on where不管是对左表还是右表进行过滤,实际都是在生成临时表以后再进行过滤的,而且对左表和右表都起作用,这与左连接left join有本质的区别!!!

最后上俩没有使用连接语句的例子:

SQL> select * from A,B where A.id = B.id and A.type = 1;
    ID       TYPE         ID      CLASS

     1          1          1          12          1          2          2

SQL> select * from A,B where A.type = 1 and A.id = B.id;

    ID       TYPE         ID      CLASS

     1          1          1          12          1          2          2

比较简单,不作解释。

总结一下:

    在使用left join时,on和where条件的区别如下:  

1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。(实际上左连接中如果and语句是对左表进行过滤的,那么不管真假都不起任何作用。如果是对右表过滤的,那么左表所有记录都返回,右表筛选以后再与左表连接返回)
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉,on后的条件用来生成左右表关联的临时表,where后的条件对临时表中的记录进行过滤。

    在使用inner join时,不管是对左表还是右表进行筛选,on and和on where都会对生成的临时表进行过滤。

在这里插入图片描述


http://chatgpt.dhexx.cn/article/C0bpOGMT.shtml

相关文章

左连接 oracle条件查询,sql 左连接查询条件and与where

用一条SQL查询一张表中不同级别的字段(字段名称相同)。 需求:用一条SQL同时查出城市id、城市name、省份id和省份name。 版本一如下 SELECT tlUp.LOCATION_ID as cityId, tlUp.LOCATION_NAME as cityName, tlDown.LOCATION_ID as provinceId, tlDown.LOCATION_NAME as province…

oracle左连接优化,关于SQL左连接效率问题

项目在开发新功能,涉及到一张表,里面数据有一百多W的条,表字段竟然有一百多个。。实在是没法再往下新增加字段了,于是就新增了一张表,用做扩展吧,通过表key来关联。后来涉及到以扩展表中某个字段作为查询条…

oracle 左连接 简写,SQL左连接

原标题:SQL左连接 今天分享一下开发中何时运用左连接进行关联查询(大牛请忽视~)。 废话不多说,直接上表结构。只有两张表作为例子,Person表为人员信息,Types为人员类型辅助表,没有定义外键关联。 记住这句话——运用左…

SQL中的左连接和右连接

SQL中的左连接和右连接 SQL中的左连接和右连接 为什么面试官喜欢问这个问题?为什么自己明明会SQL但是这个问题却模棱两可?今天为大家解决这个问题。话不多说,直接上案例~ 创建两张表 首先创建第一张表class,字段如下图所示。 …

SQL查询左连接、右连接、内连接

1、左连接的定义:是以左表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将左表所有的查询信息列出,而右表只列出ON后条件与左表满足的部分。左连接全称为左外连接,是外连接的一种。 下边以A表和B表为例子,A…

sql的左连接(LEFT JOIN)、右连接(RIGHT JOIN)、内连接(INNER JOIN)的详解

sql的左连接(LEFT JOIN)、右连接(RIGHT JOIN)、内连接(INNER JOIN)的详解: 这里以两个表的连表为例: 创建表1:为人员表,这里将它当做左表; CREA…

SQL——左连接(Left join)、右连接(Right join)、内连接(Inner join)

文章目录 前言一、概念二、例子总结 前言 最近在做SQL相关的练习,发现以前那么自信的SQL放久了不碰也变得棘手起来,特别是这一块表之间的内外连接。所以这篇是关于这个内外连接的整理。 一、概念 首先还是介绍一下这三个的定义 1.​Left join&#xf…

如何判断一个数是否为素数(质数)?

用For语句实现循环 基本思路:若一个数n能被2和√n之间的数整除(取余为0),则可判断n为素数。可从2开始测试,一直到√n为止。For语句语法规则 一般形式: for(表达式1;表达式2&#…

素数(质数)判断的五种方法

素数判断的五种方法 素数判断是我们写程序过程中经常遇见的一个问题,于是今天我简单地整理一下常用的素数判断的方法。 素数的介绍 素数定义 质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其…

Java中判断质数的方法

Java中判断质数的几种方法 说明: 1.质数:又称素数。是一个大于1的自然数(最小质数为2)。除了1和它自身外,不能被其他自然数整除的数。 >质数:用n除[2,n-1]的所有数,不能整除就是n就是质数。 2.[2,n-1]缩…

C++高效的质数的判断(2种方法)

前提准备 在开始质数的讨论之前,我们先预备一下: 质数的定义:若一个正整数除了1和它自身之外不能被任何自然数整除,则该数称为质数,也叫素数。否则为合数。 由定义可知,所有小于等于1的数既不是质数&…

C语言 判断质数很简单

算法分析:假设对于一个正数a,如果a的约数只有两个,1和它本身,那这样数叫做素数。我们对a在2—a-1之间取余,如果还能找到第三个约数,使得余数为0,那a就不是素数,如果找不到第三个约数&#xff0c…

判断一个数是否为质数(素数)的4种方法

目录 1.什么是质数? 2.如何判断是否为质数? 方法1 方法2 方法3 方法4 1.什么是质数? 首先来看质数的概念: 质数(Prime number),又称素数,指在大于1的自然数中,除了…

判断一个数是否为质数/素数——从普通判断算法到高效判断算法思路

定义:约数只有1和本身的整数称为质数,或称素数。 计算机或者相关专业,基本上大一新生开始学编程都会接触的一个问题就是判断质数,下面分享几个判断方法,从普通到高效。 1)直观判断法 最直观的方法&#xf…

【C】C语言判断是否质数

类似帖子很多了,本文侧重循序渐进逐步优化的写出判断质数的代码。 1.质数定义 质数 (素数)只能被 1 或自己整除。 同时它必须是大于 1 的整数。 1 不是质数也不是合成数。 常见的质数就是:2,3,5,7&…

判断质数(函数)

题目描述 质数是指除了1和本身之外没有其他约数的数,如7和11都是质数,而6不是质数,因为6除了约数1和6之外还有约数2和3。输入一个正整数,判断它是否为质数,如是质数则输出“Yes”,否则输出这个数的大于1的…

[C++]判断质数

最近做了几个判断质数的函数&#xff0c;记录一下&#xff1a; 一直接试除 bool is_prime3(unsigned long long n) { //slowfor (int i 2; i < n - 1; i) {if (n % i 0) {return 0;}}return 1; } note&#xff1a;比较慢 二一点优化 每次试除时其实只要除到 sqrt(n) 并且…

c++质数判断

循环和函数:质数判断 对于大于1的数,如果除了1和它本身,它不能再被其它正整数整除,那么我们说它是一个质数。要求编写程序判断给定的输入是否是质数。输入为一个整数N(1<N≤1000)。如果给出的整数N为质数,那么 输出YES;如果N不是质数,那么输出NO。

键入一个整数,判断是否是质数(两种方法)

判质数的原理就不过多赘述了&#xff0c;请移步C语言求100到500的所有质数&#xff0c;每10个数字一行打印_马拾捌的博客-CSDN博客_c语言每十个一行质数就是只能被1和他自己整除的数字第一次代码优化一个数字的因数里&#xff0c;除了1和自己以外最大的因数一定小于等于自身的一…

(三)混合边缘AI人脸对齐

目录 介绍 对齐算法 算法的实现 向检测器添加人脸对齐 修改对齐算法 下一步 在这里&#xff0c;我们将简要说明如何在Raspberry Pi上安装MTCNN、TensorFlow和Keras。然后我们在视频文件上启动人脸检测以测试性能&#xff0c;然后简要说明如何在实时模式下运行检测。最后&…