当前位置: 首页 > 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:

http://www.xdnf.cn/news/144523.html

相关文章:

  • 常见网络安全攻击类型深度剖析(二):SQL注入攻击——原理、漏洞利用演示与代码加固方法
  • MySQL 存储过程:解锁数据库编程的高效密码
  • 抓包工具Wireshark的应用解析
  • 期货有哪些种类?什么是股指、利率和外汇期货?
  • 日本企业突破机器人感知技术:人形机器人获嗅觉能力
  • 华硕NUC产品闪耀第31届中国国际广播电视信息网络展览会
  • websheet 之 HTML使用入门
  • 本地化部署实践1-ollama
  • DeepSeek本地部署手册
  • 基于随机变量的自适应螺旋飞行麻雀搜索算法(ASFSSA)优化BP神经网络,附完整完整代码
  • Linux多线程技术
  • 神经符号混合与跨模态对齐:Manus AI如何重构多语言手写识别的技术边界
  • 重置 Git 项目并清除提交历史
  • SecondScreen:智能调整屏幕比例,优化投屏体验
  • 腾讯一面面经:总结一下
  • el-upload 上传逻辑和ui解耦,上传七牛
  • pandas读取MySQL中的数据
  • 【力扣题目分享】栈专题(C++)
  • VScode远程连接服务器(免密登录)
  • 纯CSS吃豆人(JS仅控制进度)
  • YOLOv12 改进有效系列目录 - 包含卷积、主干、检测头、注意力机制、Neck上百种创新机制 - 针对多尺度、小目标、遮挡、复杂环境、噪声等问题!
  • Android 14 系统统一修改app启动时图标大小和圆角
  • 大模型在直肠癌预测及治疗方案制定中的应用研究
  • PyTorch深度学习框架60天进阶学习计划 - 第51天:扩散模型原理(二)
  • 用户案例--慧眼科技
  • 电脑技巧:路由器内部元器件介绍
  • 基于机器学习的网络钓鱼邮件智能检测与防护系统
  • 如何修复宝可梦时时刻刻冒险无法正常工作
  • 【EDA】Multi-Net Routing(多网布线)
  • 记一次调用大华抓拍SDK并发优化