【MySQL】联合查询(下)

article/2025/8/27 7:28:43

目录

一. 子查询

 单行子查询

多行子查询

多列子查询

 在from子句中使用子查询

二. 合并查询

union all

union

三.插入查询结果


上期我们讲了内连接、外连接、自连接查询,今天我们继续讲其他联合查询,没看过的之前的可以先去看看上期博客:

https://blog.csdn.net/2402_86304740/article/details/147640075https://blog.csdn.net/2402_86304740/article/details/147640075

一. 子查询

子查询就是将一个select语句查询出来的结果当成另一个select语句的查询条件,子查询也叫做嵌套查询。

子查询语法:

select *from 表名 where col_name1 {= | IN} (select col_name1 from table2 where col_name2 {= | IN} [(select ...)] ...
)

 单行子查询

示例演示:查询与“不想毕业”同学的同班同学

-- 想要查出“不想毕业”同学的同班同学,那么就要先查出“不想毕业”同学的班级
mysql> select *from student where name='不想毕业';
+----+--------------+--------+------+--------+----------+
| id | name         | sno    | age  | gender | class_id |
+----+--------------+--------+------+--------+----------+
|  8 | 不想毕业     | 200004 |   18 | 女     |        2 |
+----+--------------+--------+------+--------+----------+
1 row in set (0.03 sec)
(那么现在我们只需要不想毕业同学的class_id)mysql> select class_id from student where name='不想毕业';
+----------+
| class_id |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)
(此时就知道不想毕业同学的班级了)-- 查询班级id为2的同学
mysql> select *from student where class_id=2;
+----+--------------+--------+------+--------+----------+
| id | name         | sno    | age  | gender | class_id |
+----+--------------+--------+------+--------+----------+
|  5 | 宋江         | 200001 |   18 | 女     |        2 |
|  6 | 武松         | 200002 |   18 | 男     |        2 |
|  7 | 李逹         | 200003 |   18 | 男     |        2 |
|  8 | 不想毕业     | 200004 |   18 | 女     |        2 |
+----+--------------+--------+------+--------+----------+
4 rows in set (0.01 sec)
(此时就有这么多的学生信息)-- 将两个查询语句组合成一个语句也就是子查询语句
mysql> select *from student where class_id=(select class_id from student where name='不想毕业');
+----+--------------+--------+------+--------+----------+
| id | name         | sno    | age  | gender | class_id |
+----+--------------+--------+------+--------+----------+
|  5 | 宋江         | 200001 |   18 | 女     |        2 |
|  6 | 武松         | 200002 |   18 | 男     |        2 |
|  7 | 李逹         | 200003 |   18 | 男     |        2 |
|  8 | 不想毕业     | 200004 |   18 | 女     |        2 |
+----+--------------+--------+------+--------+----------+
4 rows in set (0.00 sec)
(此时还需要将不想毕业同学的信息给过滤掉)mysql> select *from student where class_id=(select class_id from student where name='不想毕业') and name!='不想毕业';
+----+--------+--------+------+--------+----------+
| id | name   | sno    | age  | gender | class_id |
+----+--------+--------+------+--------+----------+
|  5 | 宋江   | 200001 |   18 | 女     |        2 |
|  6 | 武松   | 200002 |   18 | 男     |        2 |
|  7 | 李逹   | 200003 |   18 | 男     |        2 |
+----+--------+--------+------+--------+----------+
3 rows in set (0.00 sec)

 代码解析:

多行子查询

示例演示:查询MySQL或者Java的成绩信息

-- 要查询这两科的成绩,就要知道这两个课程的课程id
mysql> select *from course where name in('MySQL','Java');
+----+-------+
| id | name  |
+----+-------+
|  1 | Java  |
|  3 | MySQL |
+----+-------+
2 rows in set (0.01 sec)
mysql> select id from course where name in('MySQL','Java');
+----+
| id |
+----+
|  1 |
|  3 |
+----+
2 rows in set (0.00 sec)-- 再通过课程id查找这两个课程的成绩
mysql> select *from score where course_id in(1,3);
+------+------------+-----------+
| sco  | student_id | course_id |
+------+------------+-----------+
| 70.5 |          1 |         1 |
| 98.5 |          1 |         3 |
|   60 |          2 |         1 |
|   33 |          3 |         1 |
|   68 |          3 |         3 |
|   67 |          4 |         1 |
|   23 |          4 |         3 |
|   81 |          5 |         1 |
+------+------------+-----------+
8 rows in set (0.01 sec)-- 最后将两个查询语句进行合并成一个子查询语句
mysql> select *from score where course_id in (select id from course where name in('MySQL','Java'));
+------+------------+-----------+
| sco  | student_id | course_id |
+------+------------+-----------+
| 70.5 |          1 |         1 |
| 98.5 |          1 |         3 |
|   60 |          2 |         1 |
|   33 |          3 |         1 |
|   68 |          3 |         3 |
|   67 |          4 |         1 |
|   23 |          4 |         3 |
|   81 |          5 |         1 |
+------+------------+-----------+
8 rows in set (0.01 sec)

代码分析:

多列子查询

示例演示:查询重复录⼊的分数

-- 插入重复的分数
mysql>  insert into score (sco,student_id,course_id)values(70.5,1,1),(98.5, 1, 3),(60, 2, 1);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0-- 查看一下重复数据
mysql> select *from score order by sco desc;
+------+------------+-----------+
| sco  | student_id | course_id |
+------+------------+-----------+
|   99 |          3 |         5 |
| 98.5 |          1 |         3 |
| 98.5 |          1 |         3 |
|   98 |          1 |         6 |
|   92 |          7 |         6 |
|   81 |          5 |         1 |
|   80 |          7 |         2 |
|   79 |          6 |         6 |
|   72 |          4 |         6 |
| 70.5 |          1 |         1 |
| 70.5 |          1 |         1 |
|   68 |          3 |         3 |
|   67 |          4 |         1 |
|   60 |          2 |         1 |
|   60 |          2 |         1 |
| 59.5 |          2 |         5 |
|   56 |          4 |         5 |
|   56 |          6 |         2 |
|   43 |          6 |         4 |
|   37 |          5 |         5 |
|   33 |          1 |         5 |
|   33 |          3 |         1 |
|   23 |          4 |         3 |
+------+------------+-----------+
23 rows in set (0.01 sec)
(此时就有3条重复数据了)-- 开始查找出这三条重复数据,那么重复数据的数量肯定大于1,我们可以对成绩和学生id和课程id进行分组,然后统计每个组中的数据数量,如果大于1就是重复数据了
mysql> select sco,count(*)from score group by sco,student_id,course_id having count(*)>1;
+------+----------+
| sco  | count(*) |
+------+----------+
| 70.5 |        2 |
| 98.5 |        2 |
|   60 |        2 |
+------+----------+
3 rows in set (0.01 sec)
(此时找到重复的成绩了,但是我们需要的是当前重复成绩的信息)mysql> select *from score group by sco,student_id,course_id having count(*)>1;
+------+------------+-----------+
| sco  | student_id | course_id |
+------+------------+-----------+
| 70.5 |          1 |         1 |
| 98.5 |          1 |         3 |
|   60 |          2 |         1 |
+------+------------+-----------+
3 rows in set (0.00 sec)
(此时得到重复数据的信息了,那么通过这几个成绩信息,就可以查询成绩表中的重新数据)mysql> select *from score where (sco,student_id,course_id) in(select *from score group by sco,student_id,course_id having count(*)>1);
+------+------------+-----------+
| sco  | student_id | course_id |
+------+------------+-----------+
| 70.5 |          1 |         1 |
| 98.5 |          1 |         3 |
|   60 |          2 |         1 |
| 70.5 |          1 |         1 |
| 98.5 |          1 |         3 |
|   60 |          2 |         1 |
+------+------------+-----------+
6 rows in set (0.01 sec)

 在from子句中使用子查询

示例演示:查询软件班中成绩超过平均分的成绩信息

-- 首先需要知道软件班的平均分
mysql> select avg(sc.sco) from class c,score sc where c.id=sc.course_id;
+-------------------+
| avg(sc.sco)       |
+-------------------+
| 66.61538461538461 |
+-------------------+
1 row in set (0.01 sec)-- 然后将软件班学生的成绩与平均分进行比较
mysql> select *from score sc,(select avg(sc.sco) as score from class c,score sc where c.id=sc.course_id) as tmp where sc.sco>tmp.score;
+------+------------+-----------+-------------------+
| sco  | student_id | course_id | score             |
+------+------------+-----------+-------------------+
| 70.5 |          1 |         1 | 66.61538461538461 |
| 98.5 |          1 |         3 | 66.61538461538461 |
|   98 |          1 |         6 | 66.61538461538461 |
|   68 |          3 |         3 | 66.61538461538461 |
|   99 |          3 |         5 | 66.61538461538461 |
|   67 |          4 |         1 | 66.61538461538461 |
|   72 |          4 |         6 | 66.61538461538461 |
|   81 |          5 |         1 | 66.61538461538461 |
|   79 |          6 |         6 | 66.61538461538461 |
|   80 |          7 |         2 | 66.61538461538461 |
|   92 |          7 |         6 | 66.61538461538461 |
| 70.5 |          1 |         1 | 66.61538461538461 |
| 98.5 |          1 |         3 | 66.61538461538461 |
+------+------------+-----------+-------------------+
13 rows in set (0.00 sec)

二. 合并查询

在实际应用中,我们可能需要合并多个查询出来的结果,就需要进行合并查询,使用集合操作符union,unionall

重新创建一个测试数据:

mysql> create table student1 like student;
Query OK, 0 rows affected (0.03 sec)insert into student1 (name, sno, age, gender,class_id) values
('唐三藏', '100001', 18, '男',1),
('刘备', '300001', 18, '女',  3),
('张⻜', '300002', 18, '男', 3),
('关⽻', '300003', 18, '男', 3);mysql> select *from student1;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
|  3 | 张⻜      | 300002 |   18 | 男     |        3 |
|  4 | 关⽻      | 300003 |   18 | 男     |        3 |
+----+-----------+--------+------+--------+----------+
4 rows in set (0.00 sec)

union all

示例演示:查询student1表中id<3的同学和student1表中的所有同学

-- 查询student1表中id<3的信息
mysql> select *from student1 where id<3;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
+----+-----------+--------+------+--------+----------+
2 rows in set (0.00 sec)-- 查询student1表中的所有同学
mysql> select *from student1;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
|  3 | 张⻜      | 300002 |   18 | 男     |        3 |
|  4 | 关⽻      | 300003 |   18 | 男     |        3 |
+----+-----------+--------+------+--------+----------+
4 rows in set (0.00 sec)mysql> select *from student1 where id<3 union all select *from student1;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
|  3 | 张⻜      | 300002 |   18 | 男     |        3 |
|  4 | 关⽻      | 300003 |   18 | 男     |        3 |
+----+-----------+--------+------+--------+----------+
6 rows in set (0.01 sec)
(此时就发现两个查询语句的表进行了合并)

union

示例演示:查询student1表中id<3的同学和student1表中的所有同学

-- 查询student1表中id<3的信息
mysql> select *from student1 where id<3;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
+----+-----------+--------+------+--------+----------+
2 rows in set (0.00 sec)-- 查询student1表中的所有同学
mysql> select *from student1;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
|  3 | 张⻜      | 300002 |   18 | 男     |        3 |
|  4 | 关⽻      | 300003 |   18 | 男     |        3 |
+----+-----------+--------+------+--------+----------+
4 rows in set (0.00 sec)mysql> select *from student1 where id<3 union select *from student1;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  1 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  2 | 刘备      | 300001 |   18 | 女     |        3 |
|  3 | 张⻜      | 300002 |   18 | 男     |        3 |
|  4 | 关⽻      | 300003 |   18 | 男     |        3 |
+----+-----------+--------+------+--------+----------+
4 rows in set (0.00 sec)
(此时就会发现union过滤的合并表后的重复信息)

 union和union all的区别: 

union会将合并表中的重复行进行过滤,union all则只负责合并,不进行过滤操作

三.插入查询结果

在插入数据时,MySQL也支持将查询出来的数据作为插入的数据进行插入

示例演示:将student表中软件班的学生复制到student1表中

-- 先删除student1表中的数据
mysql> delete from student1;
Query OK, 4 rows affected (0.01 sec)-- 复制数据
mysql> insert into student1 (name,sno,age,gender,class_id) select s.name,s.sno,s.age,s.gender,s.class_id from student s,class c where s.class_id=c.id and c.name='软件班';
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0-- 查询数据
mysql> select *from student1;
+----+-----------+--------+------+--------+----------+
| id | name      | sno    | age  | gender | class_id |
+----+-----------+--------+------+--------+----------+
|  5 | 唐三藏    | 100001 |   18 | 男     |        1 |
|  6 | 孙悟空    | 100002 |   18 | 女     |        1 |
|  7 | 猪悟能    | 100003 |   18 | 男     |        1 |
|  8 | 沙悟净    | 100004 |   18 | 男     |        1 |
+----+-----------+--------+------+--------+----------+
4 rows in set (0.00 sec)


http://www.hkcw.cn/article/tvfxiHGSFb.shtml

相关文章

unity—特效闪光衣服的设置

模型设置两个材质球&#xff0c;一个基础色&#xff0c;一个闪光色 闪光层设置 基础色设置

lvs-keepalived高可用群集

目录 1.Keepalived 概述及安装 1.1 Keepalived 的热备方式 1.2 keepalived的安装与服务控制 &#xff08;1&#xff09;安装keep alived (2)控制 Keepalived 服务DNF 安装 keepalived 后,执行以下命令将keepalived 服务设置为开机启动。 2.使用 Keepalived 实现双机热备 …

多端 API 兼容性设计:如何统一 iOS / Android / Web 接口规范?

在移动互联网时代&#xff0c;一个后台服务往往需要同时支撑 iOS、Android 和 Web 三端业务。当某电商App在Android端出现支付接口返回结构不一致导致崩溃&#xff0c;而iOS端却正常运行时&#xff1b;当某个Web端新功能因接口版本问题延期上线时——多端API的兼容性问题已成为…

Linux的SHELL脚本中的常用命令

一、设置主机名称 1.文件的方式 注&#xff1a;修改完毕文件后在当前的shell中是不生效的&#xff0c;如果需要看到效果&#xff0c;关闭当前shell后重新开启新的shell 2.通过命令更改主机名 注&#xff1a;hostnamectl hostname后加上你要改的主机名&#xff0c;即改即生效&…

ultraiso制作U盘镜像 针对win2012及win2016等需要特殊处理

1.按照正常操作步骤制作U盘镜像 以管理员方式运行软碟通2.正常制作镜像 3.由于磁盘格式&#xff0c;大于4G的文件是写不进去的 手动拷贝资源文件&#xff0c;右键将镜像挂载到电脑上 4.转换U盘格式 convert H:/fs:NTFS 执行该命令 此次需要保证U盘不被占用 这个时候就能存储…

【AI News | 20250529】每日AI进展

AI Repos 1、WebAgent 阿里巴巴通义实验室近日发布了WebDancer&#xff0c;一款旨在实现自主信息搜索的原生智能体搜索推理模型。WebDancer采用ReAct框架&#xff0c;通过分阶段训练范式&#xff0c;包括浏览数据构建、轨迹采样、监督微调和强化学习&#xff0c;赋予智能体自主…

【Python】3.函数与列表

文章目录 一、函数1、函数是什么&#xff1f;2、语法格式3、函数参数4、函数返回值5、变量作用域6、函数执行过程7、链式调用8、嵌套调用9、函数递归10、参数默认值11、关键字参数小结 二、列表和元组1、列表是什么&#xff0c;元组是什么&#xff1f;2、创建列表3、访问下标4、…

Arduino LCD 1602液晶显示器2(I2C总线)

LCD 1602液晶显示器2&#xff08;I2C总线&#xff09; 上一小节中我们学习了LCD1602的标准连接&#xff0c;但因为线太多&#xff0c;在实际的工作中会占用太多的Arduino的针脚&#xff0c;所以不是很实用。为了解决这个问题&#xff0c;下面我们介绍一种总线控制IIC&#xff0…

⚽【足球数据全维度解析】从基础统计到高阶分析,数据如何重塑现代足球?

足球世界正在经历一场深刻的数据革命。本文将系统介绍足球数据统计的完整体系&#xff0c;并揭示数据如何改变这项运动的训练、比赛和决策方式。 &#x1f4ca; 一、核心数据统计维度 1. 比赛基础数据 射门数据&#xff1a;场均射门/射正&#xff08;哈兰德5.2次/场&#xff0…

【C++项目】:仿 muduo 库 One-Thread-One-Loop 式并发服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;C从入门到精通 目录 &#x1f525; 前言 一&#xff1a;&#x1f525; 项目储备知识 &#x1f98b; HTTP 服务器&#x1f98b; Reactor 模型&#x1f380; 单 Reactor 单线程&#xff1a;单I/O多路…

MaaS(模型即服务)是什么?

模型即服务&#xff08;Model as a Service&#xff0c;MaaS&#xff09;是近年来随着人工智能和云计算技术发展而兴起的一种服务模式。以下是对模型即服务的详细展开&#xff1a; 1.概念与定义 ​ ​模型即服务&#xff08;MaaS&#xff09;是一种将机器学习模型作为云服务…

AI编程报错 API流式传输失败解决方案

引言 如果大家在AI编程过程中遇到以下问题&#xff0c;可参考本文的解决方案。 大家好&#xff0c;我是逍遥小欢。昨天在我的老的win10电脑上&#xff0c;安装搭建AI编程vscode和roocode环境时&#xff0c;运行提示词遇到一个错误。 报错提示:API流式传输失败 Command failed…

龙虎榜——20250529

上证指数放量收阳线&#xff0c;个股涨多跌少&#xff0c;汽车主线方向凸显。 深证指数放量收阳线&#xff0c;可以围绕主线方向做。 2025年5月29日龙虎榜行业方向分析 1. 智能驾驶&#xff08;政策落地场景延伸&#xff09; 代表标的&#xff1a;云内动力、信邦智能。 …

R3GAN训练自己的数据集

简介 简介&#xff1a;这篇论文挑战了"GANs难以训练"的广泛观点&#xff0c;通过提出一个更稳定的损失函数和现代化的网络架构&#xff0c;构建了一个简洁而高效的GAN基线模型R3GAN。作者证明了通过合适的理论基础和架构设计&#xff0c;GANs可以稳定训练并达到优异…

HackMyVM-Dejavu

信息搜集 主机发现 ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:39:60:4c, IPv4: 192.168.43.126 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.43.1 c6:45:66:05:91:88 …

vue-seamless-scroll 结束从头开始,加延时后滚动

今天遇到一个大屏需求&#xff1a; 1️⃣初始进入页面停留5秒&#xff0c;然后开始滚动 2️⃣最后一条数据出现在最后一行时候暂停5秒&#xff0c;然后返回1️⃣ 依次循环&#xff0c;发现vue-seamless-scroll的方法 ScrollEnd是监测最后一条数据消失在第一行才回调&#xff…

【实证分析】上市公司全要素生产率+5种测算方式(1999-2024年)

上市公司的全要素生产率&#xff08;TFP&#xff09;衡量企业在资本、劳动及中间投入之外&#xff0c;通过技术进步、管理效率和规模效应等因素提升产出的能力。与单纯的劳动生产率或资本生产率不同&#xff0c;TFP综合反映了企业创新能力、资源配置效率和组织优化水平&#xf…

在 Ubuntu 上安装 NVM (Node Version Manager) 的步骤

NVM (Node Version Manager) 是一个用于管理多个 Node.js 版本的工具&#xff0c;它允许您在同一台设备上安装、切换和管理不同版本的 Node.js。以下是在 Ubuntu 上安装 NVM 的详细步骤&#xff1a; 安装前准备 可先在windows上安装ubuntu 参考链接&#xff1a;https://blog.…

4. Observer / Event(观察者模式) C++

4. Observer / Event(观察者模式) C++ 1. 动机(场景) 适用于观察者对象(可以有多个)在观察某个对象(目标对象)的状态,如果该对象的状态发生改变,观察者对象都将收到通知。 举个例子,当我们要做一个文件分割器(就是将一个大文件分割成指定大小的小文件),这时还需…

多模态融合新方向:光学+AI如何智能分拣,提升塑料回收率?

【导读】 面对触目惊心的全球塑料污染&#xff08;每分钟百万瓶、年耗五万亿袋&#xff09;以及较低的塑料回收率&#xff0c;本研究聚焦提升回收效率的核心环节——自动分拣技术。尽管AMP Robotics等公司利用结合现代机器学习&#xff08;如R-CNN、YOLO系列&#xff09;的光学…