当前位置: 首页 > news >正文

【MySQL】(8) 联合查询

一、联合查询的作用

        由于范式的规则,数据分到多个表中,想要查询完整的信息,就需要联合查询多张表。比如查询学生的学生信息和所在班级的信息,就需要联合查询学生表和班级表。

二、联合查询过程

        案例:查询学生姓名为孙悟空的详细信息,包括学学个人信息和班级信息。

 # 课程表
insert into course (name) values ('Java'), ('C++'), ('MySQL'), ('操作系统'), ('计算机网络'), ('数据结构');# 班级表
insert into class(name) values ('Java001班'), ('C++001班'), ('前端001班');# 学生表
insert into student (name, sno, age, gender, enroll_date, class_id) values ('唐三藏', '100001', 18, 1, '1986-09-01', 1),('孙悟空', '100002', 18, 1, '1986-09-01', 1),('猪悟能', '100003', 18, 1, '1986-09-01', 1),('沙悟净', '100004', 18, 1, '1986-09-01', 1),('宋江', '200001', 18, 1, '2000-09-01', 2),('武松', '200002', 18, 1, '2000-09-01', 2),('李逹', '200003', 18, 1, '2000-09-01', 2),('不想毕业', '200004', 18, 1, '2000-09-01', 2);# 成绩表
insert into score (score, student_id, course_id) values(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),(60, 2, 1),(59.5, 2, 5),(33, 3, 1),(68, 3, 3),(99, 3, 5),(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),(81, 5, 1),(37, 5, 5),(56, 6, 2),(43, 6, 4),(79, 6, 6),(80, 7, 2),(92, 7, 6);

1、确定联合查询的表

        学生表 student 和班级表 class,进行笛卡尔积

2、过滤掉班级号不匹配的信息

        学生表和班级表都有 id,需要指定是哪个表的 id。

3、筛选出指定学生

4、筛选出想要的字段,并精简表名

三、内连接

        上面的示例就是内连接。 

1、语法

select 字段 from 表1 别名1, 表2 别名2 where 连接条件 and 其他条件;select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 where 其他条件;

2、示例1:查询“唐三藏”同学的成绩。

        查询的表:student、score。

        确定连接条件需要查看表结构:s.id = sc.student_id。

       其他条件:s.name = '唐三藏'。

       字段:s.name、sc.score。

3、示例2:查询所有同学的总成绩、个人信息。

        查询的表:student、score。

        连接条件:s.id = sc.student_id。

        分组查询:sc.student_id,① 唯一。② 对哪个表的列求和,就对那个表的列进行分组。

        查询字段:s.id、s.sno、s.name、s.age、s.gender、s.enroll_date、sc.s(分组后,这些字段的值对于某一组都是确定的,可以在分组后查询)、avg(sc.score)(聚合函数的值也是确定的)。

        查询结果:

4、示例3:查询所有同学的个人信息、每门课的成绩

        查询表:student、score、course。

        连接条件:

        查询结果:

        也可以使用:

        工作中尽量少对大表关联查询,最多关联 3 个表,因为很耗资源。

四、外连接

  • 左外连接:以左表为基准,显示左表所有值,显示右表匹配的值,没有匹配的就显示 NULL。
  • 右外连接:跟左外连接反着来。
  • 全连接:左、右都全显示,没有匹配的就显示 NULL。(MySQL 不支持

        内连接是有匹配的才显示,外连接没有匹配的也会显示 NULL。

1、语法

-- 左外连接,表1完全显⽰ 
select 字段 from 表名1 left join 表名2 on 连接条件;-- 右外连接,表2完全显⽰
select 字段 from 表名1 right join 表名2 on 连接条件;

2、示例1:查询没有参加考试的同学信息

        该查询就无法使用内连接完成

        查询的表:student、score。

        连接条件:s.id = sc.student_id。

        没有参加考试的同学:同学信息要全显示,没有匹配的成绩显示 NULL

        其它条件:sc.score is null。(注意不要用 =,null 与任意值做计算都是 null)

3、示例2:查询没有学生的班级

五、自连接

        自连接是自己跟自己做笛卡尔积。上面的连接都是列与列的比较,有时候我们想要同一列中行与行的比较,但MySQL 又不支持直接比较行与行。就需要用自连接,把行转为列。

        比如我们想要比较同一个学生的 score 字段的不同课程成绩:

1、示例1:显示所有 'Java' 比 'MySQL' 分数低的学生和成绩信息

        查询的表:score sc1、score sc2、student s。

        连接条件:sc1.student_id = sc2.student_id。同一个学生的成绩进行比较。(自连接)

                          sc1.student_id = student.id。

        其它条件:sc1.class_id = Java 的编号,sc2.class_id = MySQL 的编号。(选出对应的课程)。sc1.score < sc2.score。

2、示例2:通过课程名实现示例1

        有时候希望实现用户输入 2 个课程名称,就能直接查询的功能。所以先把 score 表与 class 表关联后,在对课程名进行筛选。

        查询的表:score sc1、class c1、score sc2、class c2。

        连接条件:sc1.class_id = c1.id(代表课程1)

                          sc2.class_id = c2.id(代表课程2)

                          sc1.student_id = sc2.student_id(代表同一个学生)

        其他条件:c1.name = 'Java', c2.name = 'MySQL'

                          sc1.score < sc2.score

六、子查询

        子查询就是一个 select 语句的结果是另一个 select 语句的条件,可以嵌套多层,也叫嵌套查询。子查询只是把多条的查询语句合并成一条查询语句,在工作中不能嵌套太多,影响查询效率。

1、语法

        in 表示内层的 select 返回的是一个结果集。

2、单行子查询。

        内层只返回一行数据

        示例:查询 '不想毕业' 的同班同学

        先要查询 '不想毕业' 是哪个班的(内层返回1行),然后根据班级 id 查询同班同学(外层)。最后排除 '不想毕业' 的信息。

3、多行子查询

        内层返回多行数据

        示例:查询 'Java' 或 'MySQL' 的成绩信息。

        先查询 'Java' 或 'MySQL' 的课程 id(返回2行),然后根据课程 id 查询成绩信息。

4、多列子查询

        内层返回多列数据,外层条件与内层查询的列要匹配

        示例:查询重复录入的分数。

        首先查询重复的成绩信息(分数、学生 id、课程 id,相同的分为一组,统计每组数据行数,计数大于1的则重复),再根据内层的查询结果在外层查询完整的成绩信息(成绩 id,分数、学生 id、课程 id)。

5、在 from 子句中使用子查询

        from 后面接查询的表,这个表可以是真实表或者临时表,而子查询的结果就是存储在临时表中。

        示例:查询大于 'Java001' 班平均分的成绩信息。

        先查找班级为 'Java001班' 的学生成绩,即将 class、score、student 关联,选出 class.name = 'Java001班' 的数据行,再求平均值,平均值存储在临时表中。

        再将平均值临时表与 score 表进行内连接,最后使用其它条件 score > avg。

七、合并查询

        想让多个 select 查询结果集一起返回,就用合并查询。

1、union(结果集去重)

        准备一个与 student 结构一致的 student2 表:

        插入数据:

insert into student2 (name, sno, age, gender, enroll_date, class_id) values
('唐三藏', '100001', 18, 1, '1986-09-01', 1),
('刘备', '300001', 18, 1, '1993-09-01', 3),
('张飞', '300002', 18, 1, '1993-09-01', 3),
('关羽', '300003', 18, 1, '1993-09-01', 3);

        student 表数据:

        

        查询 student 表中 id < 3 的学生和 student2 表中所有学生(因为 union 去重,所以唐三藏只有一条数据):

2、union all(结果集不去重)

3、注意事项

  • 单表可以使用合并语句,但是建议使用 or

  • 合并查询时,多张表的一定要对齐

八、插入查询结果

        插入的数据是查询的结果

        示例:将 student 表中 'C++001班' 的学生数据加入到 student2 表中。

        查看 student 表中 'C++001班' 的学生:

        将查询结果插入到 student2 表中(注意:不使用 values,null 表示给自增的 id 占位):

        插入后的 student2:

相关文章:

  • 【DE-III】基于细节增强的模态内和模态间交互的视听情感识别
  • 图像修复模型MAT(Mask-Aware Transformer)的训练、推理实战记录
  • 深入掌握Redis主从复制:原理、配置与生产级实践指南
  • python_BeautifulSoup提取html中的信息
  • 4G卡的DTU固件TCP通讯
  • MySQL 从入门到精通
  • C++23 中 constexpr 的重要改动
  • 【每天一个知识点】IPv4(互联网协议版本4)和IPv6(互联网协议版本6)
  • [贪心_7] 最优除法 | 跳跃游戏 II | 加油站
  • Unity | AmplifyShaderEditor插件基础(第三集:颜色的计算)
  • 高效DCDC电源芯片在运动控制器中的应用:设计考量、性能评估与可靠性分析
  • TortoiseGit使用图解
  • Linux进程学习【基本认知】
  • echarts坐标轴数值,生成的数值是0,100,200,300...,怎么不设置min和max的情况下,让坐标轴的数值相隔200
  • TestBrain开源程序是一款集使用AI(如deepseek)大模型自动生成测试用例、和测试用例评审、RAG知识库管理的web平台系统
  • 常见网络安全攻击类型深度剖析(三):DDoS攻击——分类、攻击机制及企业级防御策略
  • 《深入理解计算机系统》阅读笔记之第十一章 网络编程
  • React.memo 和 useMemo
  • 【金仓数据库征文】- 深耕国产数据库优化,筑牢用户体验新高度
  • python源码打包为可执行的exe文件
  • 伊朗南部港口火势蔓延,部分集装箱再次发生爆炸
  • 魔都眼·上海车展⑥|周六客流超13.5万人次,创开展新高
  • 年客流超2500万,九岁的上海国际旅游度假区有哪些文旅商体实践?
  • 中国平安一季度净赚270亿降逾26%,营运利润增2.4%
  • 云南省委常委、组织部部长刘非任浙江省委常委、杭州市委书记
  • 受折纸艺术启发可移动可变形的新型超材料问世