Young's blog Young's blog
首页
Spring
  • 前端文章1

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Young

首页
Spring
  • 前端文章1

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL高级原理及优化第一篇:MySQL执行过程及执行顺序
  • MySQL高级原理及优化第二篇: Mysql存储引擎InnoDB介绍
  • MySQL高级原理及优化第三篇: MySQL索引原理
  • MySQL高级原理及优化第四篇: MySQL事务和锁
  • MySQL高级原理及优化第五篇:MySQL集群架构
  • mysql order by 原理及优化详解
  • 聊聊数据库优化的4大手段
  • 高频面试:如何解决MySQL主从复制延时问题
  • 1万字+30张图 对mysql索引概念以及原理全方位讲解
  • 详解 Mysql LEFT JOIN和JOIN查询区别及原理
  • MySQL IN、Exist关联查询时,我们为什么建议小表驱动大表?
  • MySQL的Left、Right join(外连接)中的on条件与where条件区别
    • 面试官:MySQL连环炮,你扛得住嘛?
    • InnoDB为什么不用跳表,Redis为什么不用B+树?
    • 小林图解msql
    • mysql
    andanyang
    2022-05-02
    目录

    MySQL的Left、Right join(外连接)中的on条件与where条件区别

    数据库通过 JOIN 连接两张或多张表返回记录时,都会生成一张中间的临时表,再将这张临时表返给用户。 对主表的筛选条件,应放在 where 条件后,如果在 on 之后,则对主表筛选来说,没有任何意义。

    # on、where 执行顺序

    on的优先级,高于where。 两者后面放置相同条件,可能会导致结果集不同,就是因为优先级所致。

    # 1. mysql left join 执行原理

    MySQL 中的 LEFT JOIN 是一种表连接操作,它返回左表中所有的记录,以及符合连接条件的右表中的记录,如果右表中没有符合条件的记录,则对应的列返回 NULL 值.

    LEFT JOIN 的执行过程如下:

    1. 从左表中取出所有的记录.
    2. 对于左表中的每条记录,都在右表中查找符合连接条件的记录,并将左表和右表中符合条件的记录进行连接.
    3. 如果右表中没有符合条件的记录,则返回 NULL 值.
    4. 返回连接结果,其中包含左表和右表中符合条件的记录.

    总的来说,LEFT JOIN 是通过将左表的所有记录和右表中符合条件的记录进行连接来实现的,如果右表中没有符合条件的记录,则对应的列返回 NULL 值

    # 使用示例

    table1:

    id num
    1 111
    2 222

    table2:

    num name
    111 first
    222 second

    执行如下两条查询:

    sql1:

    SELECT
    	a.id,
    	a.num,
    	b.NAME
    FROM
    	table1 a
    	LEFT JOIN table2 b ON ( a.num = b.num AND b.NAME = 'first' );
    
    1
    2
    3
    4
    5
    6
    7

    sql2:

    SELECT
    	a.id,
    	a.num,
    	b.NAME
    FROM
    	table1 a
    	LEFT JOIN table2 b ON ( a.num = b.num )
    WHERE
    	b.NAME = 'first';
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    则,第 1 条 SQL 返回:

    id num name
    1 111 first
    2 222 (Null)

    第 2 条 SQL 返回:

    id num name
    1 111 first

    第一条 sql 的执行流程:

    首先找到 b 表的 name 为 first 的记录行on (a.num = b.num and b.name='first'),然后找到 a 的全部数据(left join),生成临时表返回数据。

    第二个 sql 的执行流程:

    先生成临时表(全量),然后执行 where 过滤b.name=’first’不为真的结果,最后返回数据。

    因为 on 会首先过滤掉不符合条件的行,然后才会进行其它运算。 执行顺序: on > where > having, 因此理论上 on 是最快的。

    多表查询时,on 比 where 更早起作用。系统首先根据各个表之间的联接条件,把多个表整合成一个临时表,再由 where 进行过滤,之后再进行计算,计算完后再由 having 过滤。

    对于 JOIN 参与的表的关联操作,如果需要不满足连接条件的行也被返回,就必需把连接条件放在 ON 后,不能放在 WHERE 后面, 如果把连接条件放在了 WHERE 后面,那么所有的 LEFT、RIGHT 等操作将不起任何作用,对于这种情况,它的效果就完全等同于 INNER 连接。

    # 结论

    on是在生成临时表的时候使用的条件,不管 on 的条件是否起到作用,都会返回左表 (主表) 的行。 where则是在生成临时表之后使用的条件,此时已经不管是否使用了left join了,只要条件不为真的行,全部过滤。

    # Tips:

    所有的 join 条件必需放在 ON 后面。 否则前面的 LEFT、RIGHT 关联将作为摆设,不起任何作用。

    # mysql 中 where 和 on 不同点

    在 MySQL 中,WHERE 和 ON 都可以用来过滤查询结果,但它们的使用场景有所不同。

    • WHERE 用于过滤行级别的数据,其条件是在表连接之后进行过滤的,也就是说,WHERE 后的条件会应用到连接后的所有数据中,包括主表和从表的数据。WHERE 语句一般放在 SQL 语句的末尾,用于筛选查询结果。
    • ON 用于指定两个表之间的连接条件,其条件是在表连接之前进行过滤的,也就是说,ON 后的条件只会应用到连接的两个表之间,而不会影响其他数据。ON 语句一般放在 SQL 语句的中间,用于指定表之间的连接条件。

    对于主表的筛选条件,应该放在 WHERE 后面,而不是放在 ON 后面。因为主表的筛选条件是在连接之后进行的,如果把主表的筛选条件放在 ON 后面,那么会先进行表连接,再进行筛选,这样会导致查询的效率变低。而把主表的筛选条件放在 WHERE 后面,可以先进行筛选,再进行表连接,这样可以提高查询的效率。所以,一般情况下,我们建议把主表的筛选条件放在 WHERE 后面。

    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
    
    1

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

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

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

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

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

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

    (4): 对于关联表我们其实可以先做子查询再做 join

    编辑 (opens new window)
    上次更新: 2024/04/19, 08:52:45
    MySQL IN、Exist关联查询时,我们为什么建议小表驱动大表?
    面试官:MySQL连环炮,你扛得住嘛?

    ← MySQL IN、Exist关联查询时,我们为什么建议小表驱动大表? 面试官:MySQL连环炮,你扛得住嘛?→

    最近更新
    01
    idea 热部署插件 JRebel 安装及破解,不生效问题解决
    04-10
    02
    spark中代码的执行位置(Driver or Executer)
    12-12
    03
    大数据技术之 SparkStreaming
    12-12
    更多文章>
    Theme by Vdoing | Copyright © 2019-2024 Young | MIT License
    浙ICP备20002744号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式