一次性讲清楚INNER JOIN、LEFT JOIN、RIGHT JOIN的区别和用法详解

文章目录

  • Join查询原理
  • Nested-Loop Join
  • INNER JOIN、LEFT JOIN、RIGHT JOIN的区别
    • INNER JOIN操作
    • LEFT JOIN操作
    • RIGHT JOIN操作
    • 总结
  • 参考

Join查询原理

查询原理:MySQL内部采用了一种叫做 Nested Loop Join(嵌套循环连接) 的算法。Nested Loop Join 实际上就是通过 驱动表的结果集 作为循环基础数据,然后一条一条的通过 该结果集 中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有第三个参与 Join,则再通过前两个表的 Join 结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复,基本上MySQL采用的是最容易理解的算法来实现join。所以驱动表的选择非常重要,驱动表的数据小可以显著降低扫描的行数。
一般情况下参与联合查询的两张表都会一大一小,如果是join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表。简单来说,驱动表就是主表,left join中的左表就是驱动表,right join中的右表是驱动表。

Nested-Loop Join

在Mysql中,使用Nested-Loop Join的算法思想去优化join,Nested-Loop Join翻译成中文则是“嵌套循环连接”。
mysql只支持一种join算法:Nested-Loop Join(嵌套循环连接),但Nested-Loop Join有三种变种:

  • Simple Nested-Loop Join:SNLJ,简单嵌套循环连接
  • Index Nested-Loop Join:INLJ,索引嵌套循环连接
  • Block Nested-Loop Join:BNLJ,缓存块嵌套循环连接
    在选择Join算法时,会有优先级,理论上会优先判断能否使用INLJ、BNLJ:Index Nested-LoopJoin > Block Nested-Loop Join > Simple Nested-Loop Join

INNER JOIN、LEFT JOIN、RIGHT JOIN的区别

接下来通过例子帮助理解他们之间的区别

首先,我们创建示例数据库和表。同时也要明确一个概念:A INNER/LEFT/RIGHT JOIN B操作中,A表被称为左表,B表被称为右表

创建示例数据库school,在数据库school下创建两张示例表:studentpunishment
创建学生基本信息表student,如下:
在这里插入图片描述

DROP TABLE IF EXISTS `punishment`;
CREATE TABLE `punishment`  (
  `student_id` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `punishment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`student_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '学生违纪处罚记录表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of punishment
-- ----------------------------
INSERT INTO `punishment` VALUES ('201400002', '张三', '大过');
INSERT INTO `punishment` VALUES ('201400006', '杨智', '留校察看');
INSERT INTO `punishment` VALUES ('201400009', '陈子丹', '小过');

创建学生违纪处罚记录表punishment,如下:
在这里插入图片描述

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `student_id` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `age` int(2) NULL DEFAULT NULL,
  `class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`student_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '学生基本信息表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('201400001', '王玉', 18, '一班', '山东省枣庄市');
INSERT INTO `student` VALUES ('201400002', '张三', 23, '二班', '江苏省南京市');
INSERT INTO `student` VALUES ('201400003', '李四', 25, '三班', '江苏省南京市');
INSERT INTO `student` VALUES ('201400004', '顾丽丽', 32, '一班', '江苏省南京市');
INSERT INTO `student` VALUES ('201400005', '邵芳芳', 29, '四班', '江苏省南京市');
INSERT INTO `student` VALUES ('201400006', '杨智', 30, '一班', '江苏省南京市');

注意,为了测试这三种JOIN操作的不同,punishment表中2014000009这个学生ID在学生基本信息表中是不存在的,这个相当于异常数据。

示例信息已经创建完毕,那么我们来看看具体的操作有什么区别。

INNER JOIN操作

首先,我们看看INNER JOIN操作,我们写个SQL语句,查询学生表中哪些学生受过处分:

SELECT 
	STU.student_id,
	STU.name,
	STU.class,
	P.punishment
FROM student AS STU
INNER JOIN punishment AS P
ON STU.student_id=P.student_id

在这里插入图片描述
分析一下上面SQL语句的执行结果,我们的查询条件是STU.student_id=P.student_id,即学生表和处分表都有的student_id的结果集,很明显,2014000002、2014000006在两表中都有

所以我们可以得出INNER JOIN操作的作用是:INNER JOIN根据ON字段标识出来的条件,查出关联的几张表中,符合该条件的记录,合并成一个查询结果集。

LEFT JOIN操作

SELECT 
	STU.student_id,
	STU.name,
	STU.class,
	P.punishment
FROM student AS STU
LEFT JOIN punishment AS P
ON STU.student_id=P.student_id

在这里插入图片描述
分析一下执行结果,LEFT JOIN操作中,比如A LEFT JOIN B,会输出 左表A 中所有的数据,同时将符合 ON条件 的 右表B 中搜索出来的结果合并到 左表A表中,如果A表中存在而在B表中不存在,则结果集中会将查询的B表字段值(如此处的P.punishment字段)设置为NULL。

所以,LEFT JOIN的作用是:LEFT JOIN 从 右表B 中将符合ON条件的结果查询出来,合并到A表中,再作为一个结果集输出。

RIGHT JOIN操作

SELECT 
	STU.student_id,
	STU.name,
	STU.class,
	P.punishment
FROM student AS STU
RIGHT JOIN punishment AS P
ON STU.student_id=P.student_id

在这里插入图片描述
分析过LEFT JOIN了,RIGHT JOIN相信你也已经明白了,“A LEFT JOIN B ON ……”是将符合ON条件的B表搜索结果合并到A表中,作为一个结果集输出。而RIGHT JOIN刚好相反, “A RIGHT JOIN B ON ……”是将符合ON条件的A表搜索结果合并到B表中,作为一个结果集输出:

总结

  • A INNER JOIN B ON……:内联操作,将符合ON条件的A表和B表结果均搜索出来,然后合并为一个结果集。
  • A LEFT JOIN B ON……:左联操作,左联顾名思义是,将符合ON条件的B表结果搜索出来,然后左联到A表上,然后将合并后的A表输出。
  • A RIGHT JOIN B ON……:右联操作,右联顾名思义是,将符合ON条件的A表结果搜索出来,然后右联到B表上,然后将合并后的B表输出。

参考

SQL中INNER、LEFT、RIGHT JOIN的区别和用法详解

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣——C语言:合并两个有序数组

88. 合并两个有序数组 - 力扣(LeetCode) 这道题有多种方法可以解决 一、暴力求解 这种方法最简单,我们只需要把两个数组合在一起然后在冒泡排序就可以了 代码如下: void merge(int* nums1, int nums1Size, int m, int* nums2…

springboot——消息中间件

消息的概念 从广义角度来说,消息其实就是信息,但是和信息又有所不同。信息通常被定义为一组数据,而消息除了具有数据的特征之外,还有消息的来源与接收的概念。通常发送消息的一方称为消息的生产者,接收消息的一方称为…

OpenAI ChatGPT-4开发笔记2024-02:Chat之text generation之completions

API而已 大模型封装在库里,库放在服务器上,服务器放在微软的云上。我们能做的,仅仅是通过API这个小小的缝隙,窥探ai的奥妙。从程序员的角度而言,水平的高低,就体现在对openai的这几个api的理解程度上。 申…

Hyperledger Fabric 核心概念与组件

要理解超级账本 Fabric 的设计,首先要掌握其最基本的核心概念与组件,如节点、交易、排序、共识、通道等。 弄清楚这些核心组件的功能,就可以准确把握 Fabric 的底层运行原理,深入理解其在架构上的设计初衷。知其然,进…

RT-Thread 线程间同步 信号量

线程间同步 在多线程实时系统中,一项工作的完成往往可以通过多个线程协调的方式共同来完成。 例如一项工作中的两个线程:一个线程从传感器中接收数据并且将数据写到共享内存中,同时另一个线程周期性地从共享内存中读取数据并发送出去显示&a…

文件或目录损坏的磁盘修复方法

文件或目录损坏是一种常见的计算机问题,可能由多种原因导致,如磁盘故障、病毒或恶意软件攻击、文件系统错误等。这些损坏可能导致数据丢失或无法访问文件,因此及时修复至关重要。本文将深入探讨文件或目录损坏的原因,并提供相应的…

JAVA毕业设计118—基于Java+Springboot的宠物寄养管理系统(源代码+数据库)

毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringboot的宠物寄养管理系统(源代码数据库)118 一、系统介绍 本系统分为管理员、用户两种角色 1、用户: 登陆、注册、密码修改、宠物寄养、寄养订单、宠物…

解决word图片格式错乱、回车图片不跟着换行的问题

解决word图片格式错乱、回车图片不跟着换行的问题 1.解决方法。 先设置为嵌入型 但是设置的话会出现下面的问题。图片显示不全。 进一步设置对应的行间距,原先设置的是固定值,需要改为1.5倍行距的形式,也就是说不能设置成固定值就可以。

SpringBoot学习(五)-Spring Security配置与应用

注:此为笔者学习狂神说SpringBoot的笔记,其中包含个人的笔记和理解,仅做学习笔记之用,更多详细资讯请出门左拐B站:狂神说!!! Spring Security Spring Security是一个基于Java的开源框架,用于在Java应用程…

ZGC垃圾收集器介绍

ZGC(The Z Garbage Collector)是JDK 11中推出的一款低延迟垃圾回收器,它的设计目标包括: 停顿时间不超过10ms;停顿时间不会随着堆的大小,或者活跃对象的大小而增加;支持8MB~4TB级别的堆&#x…

【数字图像处理】水平翻转、垂直翻转

图像翻转是常见的数字图像处理方式,分为水平翻转和垂直翻转。本文主要介绍 FPGA 实现图像翻转的基本思路,以及使用紫光同创 PGL22G 开发板实现数字图像水平翻转、垂直翻转的过程。 目录 1 水平翻转与垂直翻转 2 FPGA 布署与实现 2.1 功能与指标定义 …

【实用工具指南 三】CHAT-GPT4接入指南

好消息,CHAT-GPT4终于开放订阅了,聪明的人已经先用上了,先上个图。 但是去订阅的时候发现银行卡验证不通过,后来一查必须是老美的州才行,于是买了个美元虚拟卡 接下来就比较简单,直接找客服把GPT的充值界…

LabVIEW在高精度机器人视觉定位系统中的应用

在现代工业自动化中,精确的机器人视觉定位系统对于提高生产效率和产品质量至关重要。LabVIEW软件,以其卓越的图像处理和自动化控制功能,在这一领域发挥着重要作用。本案例将展示LabVIEW如何帮助开发和实现一个高精度的机器人视觉定位系统&…

令人绝望的固化和突破-2024-

这是继续写给自己求生之路的记录。 所有成熟稳定的行业都是相对固化的,上升通道及其严苛。 博客 我刚写博客的2015-2017这3年,其实还能带动一些学生,然后部分学生心中有火,眼里有光,也有信心自己做好,还有…

Java里的实用类

1.枚举 语法: public enum 变量名{ 值一,值二} 某个变量的取值范围只能是有限个数的值时,就可以把这个变量定义成枚举类型。 2…装箱(boxing) 和拆箱(unboxing) 装箱(boxing&…

玩转硬件之玩改朗逸中控设备

这是一个有关一件被拆卸的朗逸中控设备的故事。这个设备已经闲置多年,但是它的命运发生了转变。它被改装成了一台收音机和MP3播放器。 这个设备曾经是一辆朗逸的中控屏幕,就是因为它没有倒车影像,它就被拆了下来,被扔在了一个角落…

系列十三、集合

一、集合 1.1、概述 集合与数组类似&#xff0c;只不过集合中的数据量可以动态的变化。 1.2、体系图 1.3、List集合 1.3.1、特点 存放的数据可以重复且有序。 1.3.2、常见操作 /*** List集合常见操作* */ Test public void listOperateTest() {List<String> cityList …

1.9 day7 IO进程线程

使用消息队列完成两个进程间的通信 进程1 #include <myhead.h> struct migbuf {long a;//消息类型char b[1024];//消息正文 }; #define SIZE (sizeof(struct migbuf)-sizeof(long)) int main(int argc, const char *argv[]) {//创建key值key_t key0;if((keyftok(".…

【算法Hot100系列】下一个排列

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

conda新建、配置python3.8虚拟环境,torch-cuda1.8,torchtext0.9.0,huggingface安装transformers库

起因是我在用bert的时候&#xff0c;导包报错 Python 环境缺少 importlib.metadata 模块。importlib.metadata 是 Python 3.8 引入的模块&#xff0c;而我的环境中使用的 Python 版本为 3.7。所以我得重新配置一个python3.8的环境 准备工作 在开始菜单找到anaconda prompt(an…