【狂神】MySQL - 连表查询 Join On 详解

2024-01-25 23:50

本文主要是介绍【狂神】MySQL - 连表查询 Join On 详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 连表查询详解

 市面上有 7 种连表查询, 总共归为三大类 : 

  • 左查询 LEFT JOIN    -- 以左表为基准
  • 右查询 RIGHT JOIN   --  以右表为基准
  • 交叉查询 INNER JOIN  -- 查询两表都有的数据
操作描述
inner  join如果表中至少有一个匹配, 就返回行
left  join会从左表中返回所有的值, 即使右表中没有匹配
right  join会从右表中返回所有的值, 即使左表中没有匹配

【测试数据】

1. 创建并使用 school 数据库.

CREATE DATABASE if NOT EXISTS `school`;USE DATABASE;

2. 创建 grade 表 (年级表 ) 并构造数据.

DROP TABLE IF EXISTS `grade`;CREATE TABLE `grade`(`GradeID` INT(11) NOT NULL AUTO_INCREMENT COMMENT '年级编号', `GradeName` VARCHAR(50) NOT NULL COMMENT '年纪名称',PRIMARY KEY (`GradeID`)
) ENGINE = INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;INSERT INTO grade(GradeID,GradeName) VALUES(1,'大一');
INSERT INTO grade(GradeID,GradeName) VALUES(2,'大二');
INSERT INTO grade(GradeID,GradeName) VALUES(3,'大三');
INSERT INTO grade(GradeID,GradeName) VALUES(4,'大四');
INSERT INTO grade(GradeID,GradeName) VALUES(5,'预科班');

3.  创建 result 表 (成绩表) 并构造数据.

DROP TABLE IF EXISTS `result`;CREATE TABLE `result`(`StudentNo` INT(4) NOT NULL COMMENT '学号',`SubjectNo` INT(4) NOT NULL COMMENT '课程编号',`ExamDate` DATETIME NOT NULL COMMENT '考试时间',`StudentResult` INT(4) NOT NULL COMMENT '考试成绩',KEY `SubjectNo` (`subjectNo`)
)ENGINE=INNODB DEFAULT CHARSET = utf8;INSERT INTO `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
VALUES
(1000,1,'2023-06-25 09:00:00',85),
(1000,2,'2013-06-26 09:00:00',70),
(1000,3,'2013-06-27 09:00:00',68),
(1000,4,'2013-06-28 16:00:00',98),
(1000,5,'2013-06-29 16:00:00',68),
(1001,6,'2013-06-30 16:00:00',78),
(1002,7,'2013-07-01 16:00:00',88);

4. 创建 student 表 (学生表) 并构造数据.

DROP TABLE IF EXISTS `student`;CREATE TABLE student(`StudentNo` INT(4) NOT NULL COMMENT '学号' ,`Loginpwd` VARCHAR(20) DEFAULT NULL COMMENT '密码',`StudentName` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',`Sex` TINYINT DEFAULT NULL COMMENT '性别,0/1',`Gradeid` INT(11) DEFAULT NULL COMMENT '年纪编号',`Phone` VARCHAR(50) NOT NULL COMMENT '联系电话,不允许为空', `Address` VARCHAR(255) NOT NULL COMMENT '地址,不允许为空', `BornDate` DATETIME DEFAULT NULL COMMENT '出生时间', `Email` VARCHAR(50) NOT NULL COMMENT '邮箱账号,不允许为空',`IdentityCard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号', PRIMARY KEY (`StudentNO`),  -- 主键UNIQUE KEY `IdentityCard` (`IdentityCard`), -- 唯一索引KEY `Email` (`Email`)        -- index索引
) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
VALUES
(1000,'123456','张伟',0,2,'13800001234','北京朝阳','1980-1-1','text123@qq.com','123456434334011234'),
(1001,'123456','郭德',0,2,'13832343234','北京朝阳','1980-1-1','text123@qq.com','123456194001011234'),
(1002,'123456','李振',0,2,'13854325234','北京朝阳','1980-1-1','text123@qq.com','123456123001011234'),
(1003,'123456','刘强',0,2,'12130021234','北京朝阳','1980-1-1','text123@qq.com','123456193141011234'),
(1004,'123456','马云',0,2,'13832131234','北京朝阳','1980-1-1','text123@qq.com','123454332001011234'),
(1005,'123456','赵青',0,2,'13545441234','北京朝阳','1980-1-1','text123@qq.com','123456142101011234'),
(1006,'123456','赵强',1,3,'13805445222','广东深圳','1990-1-1','text111@qq.com','123132131301011233');

5. 创建 subject 表 (学科表)  并构造数据.

CREATE TABLE `subject`(`SubjectNo` INT(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',`SubjectName` VARCHAR(50) DEFAULT NULL COMMENT '课程名称',`ClassHour` INT(4) DEFAULT NULL COMMENT '学时',`GradeID` INT(4) DEFAULT NULL COMMENT '年纪编号',PRIMARY KEY(`SubjectNo`)
) ENGINE = INNODB DEFAULT CHARSET=utf8;INSERT INTO `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)VALUES
(1,'高等数学-1',110,1),
(2,'高等数学-2',110,2),
(3,'高等数学-3',100,3),
(4,'高等数学-4',130,4),
(5,'C语言-1',110,1),
(6,'C语言-2',110,2),
(7,'C语言-3',100,3),
(8,'C语言-4',130,4),
(9,'Java程序设计-1',110,1),
(10,'Java程序设计-2',110,2),
(11,'Java程序设计-3',100,3),
(12,'Java程序设计-4',130,4),
(13,'数据库结构-1',110,1),
(14,'数据库结构-2',110,2),
(15,'数据库结构-3',100,3),
(16,'数据库结构-4',130,4),
(17,'C#基础',130,1);

2. 连表查询示例

1. 查询参加了考试的同学 (查询列 : 学号, 姓名, 科目编号, 分数) -- 两表

【思路】

1. 分析查询的字段来自哪些表.

2. 确定使用哪种连接查询. 

3. 确定交叉点 (这两个表中哪些数据是相同的).

4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.

5. 根据需求增加 where 等值查询. (可有可无)

  • 上述字段分别来自 student 表 (学号,姓名) 和 result 表 (科目编号,分数)
  • 因为需要查询参加考试的同学, 而学生表中有些学生是没有参加考试的, 所以以成绩表为基准, 所以使用右连接查询.

【SQL 实现】

-- RIGHT JOIN
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM `student` s
RIGHT JOIN `result` r
ON s.StudentNo = r.StudentNo;

 

 如果使用左查询, 将会把没有参加考试的同学的行也查询出来, 就不符合题目要求 (查询参加考试的同学).

2.  查询缺考的同学 (学号, 姓名, 科目编号, 分数) -- 两表

【思路】

1. 分析查询的字段来自哪些表.

2. 确定使用哪种连接查询. 

3. 确定交叉点 (这两个表中哪些数据是相同的).

4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.

5. 根据需求增加 where 等值查询 (可有可无).

  • 上述字段分别来自 student 表 (学号,姓名) 和 result 表 (科目编号, 分数)
  • 因为题目需要查询未参加考试的同学, 而成绩表中只有参加了考试的同学, 所以以左表为基准, 所以使用左连接查询.

【SQL 实现】

-- LEFT JOIN
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM `student` s
LEFT JOIN `result` r
ON s.StudentNo = r.StudentNo
WHERE StudentResult IS NULL;

3. 查询参加考试的同学信息(学号, 学生姓名, 科目名称, 分数)-- 三表

【思路】

1. 分析查询的字段来自哪些表.

2. 确定使用哪种连接查询. 

3. 确定交叉点 (这两个表中哪些数据是相同的).

4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.  成绩表中的 SubjectNo = 学科表中的 SubjectNo.

5. 根据需求增加 where 等值查询 (可有可无).

  • 上述字段分别来自 student 表 (学号,姓名) ,result 表 (分数) 和 subject 表 (科目名称)
  • 先查 student , rersult 两张表, 再连 subject 第三张表.
  • 对于 student 和 result 表, 要查询参加考试的同学, 使用右连接, 而对于这两张表查询出来的结果和 subject 进行连表查询时, 没有以哪张表为基准, 所以使用 inner join 就可以了.

【SQL 实现】

1. 先查 student 表 和 result 表

SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM student s
RIGHT JOIN result r
ON s.StudentNo = r.StudentNo;

2. 再拿着查询结果与 subject 表进行连表查询

完整 SQL :

SELECT s.StudentNo '学号',StudentName '姓名',SubjectName '科目名称',StudentResult '考试成绩'
FROM student s
RIGHT JOIN result r
ON s.StudentNo = r.StudentNo
INNER JOIN `subject` sub
ON sub.SubjectNo = r.SubjectNo;

【总结】

整体查询思路 : 

1. 我要查询哪些数据  -> SELECT ...

2. 需要从哪几张表中查数据  -> FROM 表  XXX Join 连接的表 on  交叉条件.

3. 假设存在多张表 (> 2) 的查询,  先连接两张表进行查询, 再慢慢增加其他表.

这篇关于【狂神】MySQL - 连表查询 Join On 详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/645025

相关文章

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

Redis中Stream详解及应用小结

《Redis中Stream详解及应用小结》RedisStreams是Redis5.0引入的新功能,提供了一种类似于传统消息队列的机制,但具有更高的灵活性和可扩展性,本文给大家介绍Redis中Strea... 目录1. Redis Stream 概述2. Redis Stream 的基本操作2.1. XADD

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命