深入剖析多个表left join on的执行步骤原理:实战案例解析与原理探讨

文章目录

  • 文章导图
  • 前言
  • 初始化数据-建表
  • 两个表left jion
  • 多表-left jion on c.bid=b.bid分析|
    • 执行步骤和结果
      • 理解
    • 变形-修改c表数据
      • 变形1
      • 变形2
    • 总结
  • 多表-left jion on c.aid=a.aid分析
    • 执行步骤和结果
      • 理解
    • 变形-修改c表数据
      • 变形1
      • 变形2
  • 解答开头
  • 总结

Left join on系列文章
测试一下你真的理解数据库左连接了吗?
SQL连接与筛选:解析left join on和where的区别及典型案例分析
深入剖析多个表left join on的执行步骤原理:实战案例解析与原理探讨

文章导图

在这里插入图片描述

前言

日常工作中写SQL,我们会经常left join一堆表,我最多见过的有20多张的。。。(在一家外企,然后还用了一堆存储过程有几千行的,吐了。。。)那么对于left join on和前面表关联条件的时候,有的时候是紧挨着的表,有的是隔开的,有啥区别呢?具体看看这个

SELECT *
FROM a
LEFT JOIN b ON a.aid = b.aid
LEFT JOIN c ON b.bid = c.bid
LEFT JOIN d ON c.cid = d.cid
LEFT JOIN e ON d.did = e.did
LEFT JOIN f ON e.eid = f.eid

上面这种我们更好理解一点,就是一步步的去关联join on紧挨着的前面表,我们来看下面这种有啥区别?

SELECT *
FROM a
LEFT JOIN b ON a.aid = b.aid
LEFT JOIN c ON a.cid = c.cid
LEFT JOIN d ON a.did = d.did
LEFT JOIN e ON d.eid = e.eid
LEFT JOIN f ON c.fid = f.fid

这种关联关系是不是会看的眼花缭乱,一开始a和b是正常通过a.aid=b.aid,一下子join c的时候又是a.cid=c.cid,join f的时候条件又是c.fid=f.fid…

现在我们来简化一下上面的SQL,a 表主键是aid,b表是bid,c表是cid,两个语句有什么区别?如何理解?

select * from  a left join b on a.aid=b.aid  left join c on b.bid=c.bidselect * from  a left join b on a.aid=b.aid  left join c on a.aid=c.aid

这就是我们本篇文章的重点,相信理解了这两种,上面那种花里胡哨的各种left join 关联关系我们也能够手到擒来!

初始化数据-建表

这里我们把表的结构建的尽量足够简单,主要是为了理解我们的left join的整个过程

create table a
(aid    int          not nullprimary key,a_name varchar(100) null
);create table b
(bid int not nullprimary key,aid int null);create table c
(cid    int          not nullprimary key,bid    int          null,aid    int          null,c_name varchar(100) null
);

插入一些初始化数据

INSERT INTO bank.a (aid, a_name) VALUES (1, 'a1');
INSERT INTO bank.a (aid, a_name) VALUES (2, 'a2');
INSERT INTO bank.a (aid, a_name) VALUES (3, 'a3');INSERT INTO bank.b (bid, aid, b_name) VALUES (1, 1, 'b1');
INSERT INTO bank.b (bid, aid, b_name) VALUES (2, 2, 'b2');INSERT INTO bank.c (cid, bid, aid, c_name) VALUES (1, 1, 1, 'c1');
INSERT INTO bank.c (cid, bid, aid, c_name) VALUES (2, 2, 2, 'c2');

a表数据

aida_name
1a1
2a2
3a3

b表数据

bidaidb_name
11b1
22b2

c表数据

cidbidaidc_name
111c1
222c2

两个表left jion

如果只是2个表连接,我在之前的文章已经分析的很清楚了SQL连接与筛选:解析left join on和where的区别及典型案例分析

SELECT * FROM a LEFT JOIN b ON a.aid = b.aid

执行结果应该是下面这个样子,这里就不过多解释,不理解可以看我之前的文章

aida_namebidaidb_name
1a111b1
2a222b2
3a3

那么现在再多left jion 一张表(或者多张表),原理是类似的,但是会分为2种前情况,

  • 一种是left join紧挨着的这张表,也就是在原有2表关联的基础上加上left jion on c.bid=b.bid,但是它的left join是紧挨着的b表
  • 一种是left join非紧挨着的表,也就是在原有2表关联的基础上加上left jion on c.aid=a.aid,但是它的left join是非紧挨着的a表

接下来我们分别解析这两种情况

多表-left jion on c.bid=b.bid分析|

这种查询适用于你想要根据表b的某些条件或关系来过滤或连接表c的情况。这种情况下,表c与表a的关联是间接的,通过表b实现。

SQL语句如下:

SELECT *
FROM aLEFT JOIN b ON a.aid = b.aidLEFT JOIN c ON b.bid = c.bid

执行步骤和结果

  1. 第一步: 执行 a LEFT JOIN b ON a.aid = b.aid

    • 这会将表 a 中的每一行与表 b 中的行进行连接,条件是 a.aid = b.aid
    • 如果表 b 中没有对应的 aid,则结果中 b 的列将填充 NULL
  2. 第二步: 对第一步的结果再进行 LEFT JOIN c ON b.bid = c.bid

    • 这会将第一步的结果与表 c 中的行进行连接,条件是 b.bid = c.bid
    • 如果表 c 中没有对应的 bid,则结果中 c 的列将填充 NULL

image-20240713122236470

理解

  • 如果表 b 中没有匹配 a.aid 的行,那么 bc 的所有列都会是 NULL
  • 即使 ab 有匹配,但 b.bid 在表 c 中没有匹配的行,c 的列也会是 NULL

变形-修改c表数据

变形1

第一种情况,我们来修改C表数据,将bid由原来的2,修改成了3

cidbidaidc_name
111c1
23(由2修改成了3)3c2

而原来的b表是没有bid=3的数据,那么继续执行原来的SQL,结果如下

  • c表通过bid与b表关联,对于b表的bid=1能找到,所以正常显示了c表的数据
  • 对于b表的bid=2,在c表找不到关联数据,就显示NULL

image-20240713121812692

变形2

第二种情况,我们来修改C表数据,将bid由原来的2,修改成了1

cidbidaidc_name
111c1
21(由2修改成了1)3c2

对于b表的bid=1,会再c表中找到2条数据,所以b表bid=1数据显示2遍一样的,然后再对应上c表的2条不一样的数据

image-20240713124021452

总结

以上这种left jion on c.bid=b.bid再多关联一张表c,分析起来和2张表关联a和b是一样的,我们这里只是多举几种例子让大家更深刻理解一下

接下来的left jion on c.aid=a.aid才是我们的重点,也就是关联的表是前面的表,也就是不是挨着的。

多表-left jion on c.aid=a.aid分析

这种查询适用于当你直接在表a和表c之间建立关系时。这里表b的加入不影响表a与表c之间的连接。

SELECT *
FROM aLEFT JOIN b ON a.aid = b.aidLEFT JOIN c ON a.aid = c.aid;

执行步骤和结果

  1. 第一步: 执行 a LEFT JOIN b ON a.aid = b.aid

    • 这部分和第一个查询是相同的,将表 a 和表 b 进行连接,条件是 a.aid = b.aid
    • 如果没有匹配的 aid,则 b 的列将填充 NULL
  2. 第二步: 对第一步的结果再进行 LEFT JOIN c ON a.aid = c.aid

    • 这会将第一步的结果与表 c 中的行进行连接,条件是 a.aid = c.aid
    • 如果表 c 中没有对应的 aid,则结果中 c 的列将填充 NULL

image-20240713130424223

结果分析:

  • 忽略b表数据,只看当前关联的a和c表即可
  • 可以发现a表的aid=1,2都能在c表找到数据,所以c表数据也是全的

理解

简单来说,我们其实在每一次关联的时候,只看关联的两个表的数据,中间的别的表不管有多少个,都不用管,即可

  • 不论表 b 是否有匹配的行,ac 都是直接连接在一起的,条件是 a.aid = c.aid
  • 如果 a.aid 在表 c 中没有匹配的行,c 的列将会是 NULL,无论 b 是否有匹配的 bid

变形-修改c表数据

变形1

第一种情况,我们同样来修改C表数据,将aid由原来的2,修改成了4

cidbidaidc_name
111c1
224(由2修改成了4)c2

而原来的a表是没有aid=4的数据,那么继续执行原来的SQL,结果如下

image-20240713131833810

  • c表通过aid与a表关联,对于a表的aid=1能找到,所以正常显示了c表的数据
  • 对于c表的aid=4,在a表找不到关联数据,就显示NULL

变形2

第二种情况,我们来修改c表数据,将aid由原来的2,修改成了1

cidbidaidc_name
111c1
221(由2修改成了1)c2

对于a表的aid=1,会再c表中找到2条数据,所以a表aid=1数据显示2遍一样的,然后再对应上c表的2条不一样的数据

image-20240713132249605

解答开头

那么我们再来看下最开头的SQL

SELECT *
FROM a
LEFT JOIN b ON a.aid = b.aid
LEFT JOIN c ON a.cid = c.cid
LEFT JOIN d ON a.did = d.did
LEFT JOIN e ON d.eid = e.eid
LEFT JOIN f ON c.fid = f.fid

让我们逐步解析这个查询:

  1. 从表 a 开始

    SELECT *
    FROM a
    
  2. 左连接表 b

    LEFT JOIN b ON a.aid = b.aid
    

    这意味着表 a 中的每一行都会与表 baid 相等的行进行匹配。如果表 b 中没有匹配的行,结果中对应表 b 的列将包含 NULL 值。

  3. 左连接表 c

    LEFT JOIN c ON a.cid = c.cid
    

    类似地,表 a 中的每一行会与表 ccid 相等的行进行匹配。

  4. 左连接表 d

    LEFT JOIN d ON a.did = d.did
    

    a 中的每一行会与表 ddid 相等的行进行匹配。

  5. 左连接表 e

    LEFT JOIN e ON d.eid = e.eid
    

    这里需要注意的是,表 e 是通过表 d 连接的,而不是直接通过表 a。这意味着表 d 中的每一行会与表 eeid 相等的行进行匹配。

  6. 左连接表 f

    LEFT JOIN f ON c.fid = f.fid
    

    类似地,表 f 是通过表 c 连接的,而不是直接通过表 a。表 c 中的每一行会与表 ffid 相等的行进行匹配。

总结一下,这个查询的结果将包含表 a 中的所有行,以及与表 bcdef 中匹配的行。如果某个表中没有匹配的行,结果中对应该表的列将包含 NULL 值。

总结

这两条SQL其实理解了以后,我们会发现其他类似的SQL执行步骤和原理都是一样的

select * from a left join b on a.aid=b.aid left join c on b.bid=c.bidselect * from a left join b on a.aid=b.aid left join c on a.aid=c.aid

其实大的前提就是我们要记住:

  1. 我们在每一次关联的时候,只看当前执行到的关联的两个表的数据,中间的别的表不管有多少个,都不用管即可
  2. 比如当前执行left join on a.aid=b.bid,那么我们主要关注a表和b表之间的数据
  3. 然后继续执行到left join on a.aid=b.bid left join a.aid=c.aid时,就是在前面数据的基础上 (也就是执行完SELECT * FROM a LEFT JOIN b ON a.aid = b.aid,然后把这个数据当做一个整体) ,再去看我们关联的表即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/45780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​Chrome 插件: GoFullPage 一键搞定全网页截图

在互联网时代,网页截图已成为我们日常工作和生活中不可或缺的部分。无论是保存重要信息、制作教程,还是分享有趣的内容,截图功能都显得尤为重要。然而,常规的截图工具往往只能截取当前屏幕的内容,对于长网页则显得力不…

做个简单的知识付费网站需要什么方式

网站是线上承载信息宣传的主要工具之一,也是企业公司发展的重要工具之一,除了固定信息呈现外,还有不少商家具备各种方式的干货输出能力,或者想以内容售卖获得一定营收。 如教培机构、自媒体、网校、知识生产者、领域达人等都具备…

【unity笔记】九、Unity添加串口通信

unity仿真使用虚拟串口调试。下面为简单流程。 常用串口调试软件在这里下载。 1.虚拟串口 添加虚拟串口,这里使用com1 com2 2. 串口调试 在这里为虚拟串口发送消息。 3. unity配置 3.1 设置 在文件->生成设置->玩家设置->玩家->其他设置 中找到…

【机器学习】逻辑回归的原理、应用与扩展

文章目录 一、逻辑回归概述二、Sigmoid函数与损失函数2.1 Sigmoid函数2.2 损失函数 三、多分类逻辑回归与优化方法3.1 多分类逻辑回归3.2 优化方法 四、特征离散化 一、逻辑回归概述 逻辑回归是一种常用于分类问题的算法。大家熟悉的线性回归一般形式为 Y a X b \mathbf{Y}…

初学SpringMVC之 JSON 篇

JSON(JavaScript Object Notation,JS 对象标记)是一种轻量级的数据交换格式 采用完全独立于编程语言的文本格式来存储和表示数据 JSON 键值对是用来保存 JavaScript 对象的一种方式 比如:{"name": "张三"}…

「Pytorch」roLabelImg 图像异常旋转 bug

在进行Yolo-obb 模型训练的时候需要标注旋转框,roLabelImg 是比较推荐的一款旋转框标注工具,既可以标注正常的矩形框,还可以标注旋转框 roLabelImg Github 地址:https://github.com/HumanSignal/labelImg 但是在使用过程中遇到了…

SpringCloud学习

认识微服务 1.单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署 优点:架构简单 部署成本低 缺点:耦合度高 2.分布式架构:根据业务功能对系统进行拆分,每个业务模块作为独立项目开发&…

k8s record 20240710 监控

不是adaptor 是opetator 案例 监控有了,日志搜集呢? 一、kubelet 的小弟 kubelet — 负责维护容器的生命周期,节点和集群其他部分通信 cAdvisor 集成在 Kubernetes 的 kubelet 中,能够自动发现和监控集群中所有的容器。dockers…

创业者一定要做好时间管理

2024.7.5 最近接了两个项目,给我拖入了战争泥潭,耗费了大量的时间和精力。再加上今天不知道咋回事,有好多客户来咨询,就搞得人很疲惫,脑袋快炸了一样,感觉再这样下去会积怨成疾。现在能深刻的体会到&#x…

YOLOv5白皮书-第Y5周:yolo.py文件解读

本文为365天深度学习训练营 中的学习记录博客 原作者:K同学啊|接辅导、项目定制 本次训练是在前文《YOLOv5白皮书-第Y2周:训练自己的数据集》的基础上进行的。 前言 文件位置:./models/yolo.Py 这个文件是YOLOv5网络模型的搭建文件,如果你想改进YOLOv5&…

抖音短视频矩阵管理系统搭建全攻略:功能详解与实战应用

在短视频时代,抖音已经成为众多企业、网红、个人创作者不可或缺的传播平台。然而,如何高效管理多个抖音账号,实现内容、数据、粉丝的全方位掌控,成为了摆在大家面前的一道难题。本文将为大家深入解析抖音短视频矩阵管理系统的搭建…

Linux内核中的双向链表介绍

参考文章:https://www.cnblogs.com/liangliangge/p/11359196.html 相关结构体和api的介绍 1.1 struct list_head 用来创建双向循环链表的结构 1.2 INIT_LIST_HEAD 双向链表初始化,让一个链表节点首尾相连 1.3 list_add和list_add_tail 给链表增加一个结点 list_add :…

从0开始学习informer

目录 informer特点informer原理attention计算KL散度 backbone网络部分encoder输入输出部分embadding这里就不讲了 和transfomer一样EncoderStack decoder部分接下来就是最关键的结构 关于如何将输入经过注意力得到结果 结束,代码会放到下一篇讲 这里是原理 informer…

基于GIS矿产勘查靶区优选技术

定义: 找矿远景区(ore-finding prospect): 一般将中小比例尺(小于等于1:10万)成矿预测所圈定的找矿有利地段(preferable ore-finding area)成为找矿远景区 找矿靶区(ore-finding t…

车流量统计YOLOV8+DEEPSORT

车流量统计,YOLOV8NANODEEPSORT资源-CSDN文库 车流量统计YOLOV8DEEPSORT,目前支持PYTHON,C开发 PYTHON版本,需要YOLOV8,依赖PYTORCH C版本,只需要OPENCV

MYSQL的面试题

目录 一.数据库的约束类型 一.创建数据库、修改数据库名、修改表名,修改列名、修改某个属性的语法 三.索引的类型、优缺点以及使用场景 四.索引的常见的索引数据结构 五.数据库中常用的锁 六.事务的四大特性 七.什么是脏读?幻读?不可重…

技术周总结 2024.07.08~07.14(算法,Python,Java,Scala,PHP)

文章目录 一、07.13 周六1.0)算法题:字符串中的单词反转1.1) 问题01:可靠性计算中的MTTR MTTF MTBF 分别指什么?他们之间有什么联系?MTTR (Mean Time to Repair)MTTF (Mean Time to Failure)MTBF (Mean Time Between F…

vsCode 格式化代码及安装的插件

背景: 开发过程用的比较顺手的插件,首先看概览,然后分开发场景分别介绍。。。原生、vue2、vue3、react 效果展示: 不分前端开发框架,都在使用的几款插件: 插件官网链接:点击跳转官网 使用他能…

深入解析香橙派 AIpro开发板:功能、性能与应用场景全面测评

文章目录 引言香橙派AIpro开发板介绍到手第一感觉开发板正面开发板背面 性能性能概况性能体验 应用场景移植操作系统香橙派 AIpro开发板支持哪些操作系统?烧写操作系统到SD卡中启动开发板的步骤查看系统提供的事例程序体验——开发的简洁性 视频播放展示ffmpeg简介f…

C++ 语法习题(2)

第三讲 循环语句 1.偶数 编写一个程序&#xff0c;输出 1 到 100之间&#xff08;包括 1 和 100&#xff09;的全部偶数。 输入格式 无输入。 输出格式 输出全部偶数&#xff0c;每个偶数占一行。 输入样例 No input输出样例 2 4 6 ... 100 参考代码: #include <i…