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

MySQL-联合查询

1.简介

1.1为什么要使用联合查询

在数据设计时由于范式的要求,数据被拆分到多个表中,那么要查询⼀个条数据的完整信息,就
要从多个表中获取数据,如下图所⽰:要获取学⽣的基本信息和班级信息就要从学⽣表和班级表中获取,这时就需要使⽤联合查询,这⾥的联合指的是多个表的组合。

 1.2多表联合查询时MYSQL内部是如何进行计算的

参与查询的所有表取笛卡儿积,结果集在临时表中

 观察哪些记录是有效数据,根据两个表的关联关系过滤掉⽆效数据

 如果联合查询表的个数越多,表中的数据量越⼤,临时表就会越⼤,所以根据实际情况确定联合查询表的个数

1.3构造练习案例数据

# 课程表
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.4案例:一个完整的联合查询的过程

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

1.确定参与查询的表,学生表和班级表

# 在from后同时写所有参与查询的表,并⽤逗号隔开
mysql> select * from student, class;
+----+--------------+--------+------+--------+-------------+----------+----+---
-----------+
| id | name | sno | age | gender | enroll_date | class_id | id | name |
+----+--------------+--------+------+--------+-------------+----------+----+---
-----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 3 | 前端001班 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 2 | C++001班 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 3 | 前端001班 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 2 | C++001班 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 3 | 前端001班 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 2 | C++001班 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 3 | 前端001班 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 2 | C++001班 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 1 | 3 | 前端001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 1 | 2 | C++001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 1 | 3 | 前端001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 1 | 2 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 1 | 3 | 前端001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 1 | 2 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 1 | 3 | 前端001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 1 | 2 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
+----+--------------+--------+------+--------+-------------+----------+----+---
-----------+
24 rows in set (0.00 sec)

2.确定连接条件,student表中的class_id与class表中id列的值相等

# 在where⼦句中加⼊连接条件
mysql> select * from student, class where student.class_id = class.id;
+----+--------------+--------+------+--------+-------------+----------+----+---
---------+
| id | name | sno | age | gender | enroll_date | class_id | id | name |
+----+--------------+--------+------+--------+-------------+----------+----+---
---------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
+----+--------------+--------+------+--------+-------------+----------+----+---
---------+
8 rows in set (0.00 sec)

3.加入查询条件

# 依题意添加where条件
mysql> select * from student, class where student.class_id = class.id and name 
= '宋江';
ERROR 1052 (23000): Column 'name' in where clause is ambiguous# 由于两个表中都有name列,所以MySQL不清楚具体要使⽤哪个列,这时可以⽤“表名.列号”的⽅式指
定具体的列
# 得到⽬标记录⾏mysql> select * from student, class where student.class_id = class.id and
student.name = '宋江';
+----+--------+--------+------+--------+-------------+----------+----+------------+
| id | name | sno | age | gender | enroll_date | class_id | id | name  |
+----+--------+--------+------+--------+-------------+----------+----+------------+
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 1 | 1 | Java001班 |
+----+--------+--------+------+--------+-------------+----------+----+------------+
1 row in set (0.00 sec)

4.精减查询结果字段

selectstudent.id, student.name, student.sno, student.age, student.gender, student.enroll_date, class.name 
fromstudent, class 
wherestudent.class_id = class.id 
andstudent.name = '宋江';
+----+--------+--------+------+--------+-------------+------------+
| id | name | sno | age | gender | enroll_date | name |
+----+--------+--------+------+--------+-------------+------------+
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | Java001班 |
+----+--------+--------+------+--------+-------------+------------+
1 row in set (0.00 sec)

5.可以为表名指定别名

selects.id, s.name, s.sno, s.age, s.gender, s.enroll_date, c.name 
fromstudent s , class c 
wheres.class_id = c.id 
ands.name = '宋江';+----+--------+--------+------+--------+-------------+------------+
| id | name | sno | age | gender | enroll_date | name |
+----+--------+--------+------+--------+-------------+------------+
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | Java001班 |
+----+--------+--------+------+--------+-------------+------------+
1 row in set (0.00 sec)

2.内连接

2.1语法

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

2.2示例

查询“唐三藏”同学的成绩

mysql> select s.name, sc.score from student s join score sc on sc.student_id = 
s.id where s.name = '唐三藏';
+-----------+-------+
| name | score |
+-----------+-------+
| 唐三藏 | 70.5 |
| 唐三藏 | 98.5 |
| 唐三藏 | 33 |
| 唐三藏 | 98 |
+-----------+-------+
4 rows in set (0.00 sec)
查询所有同学的总成绩,及同学的个⼈信息
mysql> select s.name, sum(sc.score) from student s, score sc where
sc.student_id = s.id group by (s.id);
+-----------+---------------+
| name | sum(sc.score) |
+-----------+---------------+
| 唐三藏 | 300 |
| 孙悟空 | 119.5 |
| 猪悟能 | 200 |
| 沙悟净 | 218 |
| 宋江 | 118 |
| 武松 | 178 |
| 李逹 | 172 |
+-----------+---------------+
7 rows in set (0.00 sec)

Group by使用了student.id进行分组,查询表列表中的student.name没有出现在Group by分组中,也没有包含在聚合函数中,这是因为SQL规定在Group by分组查询时,如果查询列表中的列没 有出现在GROUP BY⼦句中,但这些列的值在每个分组内部是相同的,那么它们可以出现在查询结果中。

 查询所有同学每⻔课的成绩,及同学的个⼈信息

selects.id as id,s.name as 姓名,s.sno as 学号,s.gender as 性别,c.name as 班级,sc.score as 分数
fromstudent s, course c, score sc
wheres.id = sc.student_id
andc.id = sc.course_id
order bys.id;
# 结果集中没有"不想毕业"同学的成绩,因为score表中没有这位同学的记录
+----+-----------+--------+--------+-----------------+--------+
| id | 姓名 | 学号 | 性别 | 班级 | 分数 |
+----+-----------+--------+--------+-----------------+--------+
| 1 | 唐三藏 | 100001 | 1 | Java | 70.5 |
| 1 | 唐三藏 | 100001 | 1 | MySQL | 98.5 |
| 1 | 唐三藏 | 100001 | 1 | 计算机⽹络 | 33 |
| 1 | 唐三藏 | 100001 | 1 | 数据结构 | 98 |
| 2 | 孙悟空 | 100002 | 1 | Java | 60 |
| 2 | 孙悟空 | 100002 | 1 | 计算机⽹络 | 59.5 |
| 3 | 猪悟能 | 100003 | 1 | Java | 33 |
| 3 | 猪悟能 | 100003 | 1 | MySQL | 68 |
| 3 | 猪悟能 | 100003 | 1 | 计算机⽹络 | 99 |
| 4 | 沙悟净 | 100004 | 1 | Java | 67 |
| 4 | 沙悟净 | 100004 | 1 | MySQL | 23 |
| 4 | 沙悟净 | 100004 | 1 | 计算机⽹络 | 56 |
| 4 | 沙悟净 | 100004 | 1 | 数据结构 | 72 |
| 5 | 宋江 | 200001 | 1 | Java | 81 |
| 5 | 宋江 | 200001 | 1 | 计算机⽹络 | 37 |
| 6 | 武松 | 200002 | 1 | C++ | 56 |
| 6 | 武松 | 200002 | 1 | 操作系统 | 43 |
| 6 | 武松 | 200002 | 1 | 数据结构 | 79 |
| 7 | 李逹 | 200003 | 1 | C++ | 80 |
| 7 | 李逹 | 200003 | 1 | 数据结构 | 92 |
+----+-----------+--------+--------+-----------------+--------+
20 rows in set (0.00 sec)

3.外连接

外连接分为左外连接、右外连接和全外连接三种类型,MySQL不⽀持全外连接。
左外连接:返回左表的所有记录和右表中匹配的记录。如果右表中没有匹配的记录,则结果集中对应字段会显⽰为NULL。
右外连接:与左外连接相反,返回右表的所有记录和左表中匹配的记录。如果左表中没有匹配的记录,则结果集中对应字段会显⽰为NULL。
全外连接:结合了左外连接和右外连接的特点,返回左右表中的所有记录。如果某⼀边表中没有匹配的记录,则结果集中对应字段会显⽰为NULL。

3.1语法

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

3.2示例

查询没有参加考试的同学信息

# 左连接以JOIN左边的表为基准,左表显⽰全部记录,右表中没有匹配的记录⽤NULL填充
mysql> select s.id, s.name, s.sno, s.age, sc.* from student s LEFT JOIN score 
sc on sc.student_id = s.id;
+----+--------------+--------+------+------+-------+------------+-----------+
| id | name | sno | age | id | score | student_id | course_id |
+----+--------------+--------+------+------+-------+------------+-----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 70.5 | 1 | 1 |
| 1 | 唐三藏 | 100001 | 18 | 2 | 98.5 | 1 | 3 |
| 1 | 唐三藏 | 100001 | 18 | 3 | 33 | 1 | 5 |
| 1 | 唐三藏 | 100001 | 18 | 4 | 98 | 1 | 6 |
| 2 | 孙悟空 | 100002 | 18 | 5 | 60 | 2 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 6 | 59.5 | 2 | 5 |
| 3 | 猪悟能 | 100003 | 18 | 7 | 33 | 3 | 1 |
| 3 | 猪悟能 | 100003 | 18 | 8 | 68 | 3 | 3 |
| 3 | 猪悟能 | 100003 | 18 | 9 | 99 | 3 | 5 |
| 4 | 沙悟净 | 100004 | 18 | 10 | 67 | 4 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 11 | 23 | 4 | 3 |
| 4 | 沙悟净 | 100004 | 18 | 12 | 56 | 4 | 5 |
| 4 | 沙悟净 | 100004 | 18 | 13 | 72 | 4 | 6 |
| 5 | 宋江 | 200001 | 18 | 14 | 81 | 5 | 1 |
| 5 | 宋江 | 200001 | 18 | 15 | 37 | 5 | 5 |
| 6 | 武松 | 200002 | 18 | 16 | 56 | 6 | 2 |
| 6 | 武松 | 200002 | 18 | 17 | 43 | 6 | 4 |
| 6 | 武松 | 200002 | 18 | 18 | 79 | 6 | 6 |
| 7 | 李逹 | 200003 | 18 | 19 | 80 | 7 | 2 |
| 7 | 李逹 | 200003 | 18 | 20 | 92 | 7 | 6 |
| 8 | 不想毕业 | 200004 | 18 | NULL | NULL | NULL | NULL |
+----+--------------+--------+------+------+-------+------------+-----------+
21 rows in set (0.00 sec)# 过滤参加了考试的同学
mysql> select s.* from student s LEFT JOIN score sc on sc.student_id = s.id 
where sc.score is null;
+----+--------------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+--------------+--------+------+--------+-------------+----------+
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 1 |
+----+--------------+--------+------+--------+-------------+----------+
1 row in set (0.00 sec)
查询没有学⽣的班级
# 右连接以JOIN右边的表为基准,右表显⽰全部记录,左表中没有匹配的记录⽤NULL填充
mysql> select * from student s RIGHT JOIN class c on c.id = s.class_id;
+------+--------------+--------+------+--------+-------------+----------+----+--------------+
| id | name | sno | age | gender | enroll_date | class_id | id | name |
+------+--------------+--------+------+--------+-------------+----------+----+--------------+
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | Java001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| NULL | NULL | NULL | NULL | NULL | NULL | NULL | 3 | 前端001班 |
+------+--------------+--------+------+--------+-------------+----------+----+--------------+# 过滤有学⽣的班级
mysql> select c.* from student s RIGHT JOIN class c on c.id = s.class_id where
s.id is null;
+----+--------------+
| id | name |
+----+--------------+
| 3 | 前端001班 |
+----+--------------+
1 row in set (0.00 sec)

4.自连接

4.1应用场景

⾃连接是⾃⼰与⾃⼰取笛卡尔积,可以把⾏转化成列,在查询的时候可以使⽤where条件对结果进⾏ 过滤,或者说实现⾏与⾏之间的⽐较。在做表连接时为表起不同的别名。
# 不为表指定别名
mysql> select * from score, score;
ERROR 1066 (42000): Not unique table/alias: 'score'# 指定别名
mysql> select * from score s1, score s2;

4.2示例

显示所有“MySQL”成绩比“JAVA”成绩高的成绩信息

# ⾸先分两步进⾏,先查出JAVA和MySQL的课程Id,分别为1和3
mysql> select * from course where name = 'Java' or name = 'MySQL';
+----+-------+
| id | name |
+----+-------+
| 1 | Java |
| 3 | MySQL |
+----+-------+
2 rows in set (0.00 sec)# 再查询成绩表中,JAVA成绩⽐MySQL成绩好的信息
mysql> select s1.* from score s1, score s2 where s1.student_id = s2.student_id 
and s1.course_id = 3 and s2.course_id = 1 and s1.score > s2.score;
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
| 2 | 98.5 | 1 | 3 |
| 8 | 68 | 3 | 3 |
+----+-------+------------+-----------+
2 rows in set (0.00 sec)# 结合在⼀起进⾏查询
select s1.* fromscore s1, score s2, course c1,course c2
wheres1.student_id = s2.student_id
ands1.course_id = c1.id
ands2.course_id = c2.id 
ands1.score > s2.score
andc1.`name` = 'MySQL'
andc2.`name` = 'Java';
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
|  2 |  98.5 |          1 |         3 |
|  8 |    68 |          3 |         3 |
+----+-------+------------+-----------+
2 rows in set (0.00 sec)

4.3表连接练习

显⽰所有"MySQL"成绩⽐"JAVA"成绩⾼的学⽣信息和班级以及成绩信息
# 相关的表全部加⼊连接,并确定连接条件
select stu.name as 姓名, c.name as 班级, s1.score as MySQL分数, s2.score as Java
分数 fromscore s1, score s2, course c1,course c2,student stu,class c
wheres1.student_id = s2.student_id
ands1.course_id = c1.id
ands2.course_id = c2.id 
ands1.score > s2.score
andstu.id = s1.student_id
andstu.class_id = c.id
andc1.`name` = 'MySQL'
andc2.`name` = 'Java';+-----------+------------+-------------+------------+
| 姓名 | 班级 | MySQL分数 | Java分数 |
+-----------+------------+-------------+------------+
| 唐三藏 | Java001班 | 98.5 | 70.5 |
| 猪悟能 | Java001班 | 68 | 33 |
+-----------+------------+-------------+------------+
2 rows in set (0.00 sec)

5.子查询

⼦查询是把⼀个SELECT语句的结果当做别⼀个SELECT语句的条件,也叫嵌套查询

5.1语法

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

5.2单行子查询

嵌套的查询中只返回⼀⾏数据
⽰例:查询与"不想毕业"同学的同班同学
mysql> select * from student where class_id = (select class_id from student 
where name = '不想毕业');
+----+--------------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+--------------+--------+------+--------+-------------+----------+
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
+----+--------------+--------+------+--------+-------------+----------+
4 rows in set (0.00 sec)

5.3多行子查询

嵌套的查询中返回多⾏数据,使⽤[NOT] IN关键字
⽰例:查询"MySQL"或"Java"课程的成绩信息
mysql> select * from score where course_id in (select id from course where
name = 'Java' or name = 'MySQL');
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
|  1 |  70.5 |          1 |         1 |
|  5 |    60 |          2 |         1 |
|  7 |    33 |          3 |         1 |
| 10 |    67 |          4 |         1 |
| 14 |    81 |          5 |         1 |
|  2 |  98.5 |          1 |         3 |
|  8 |    68 |          3 |         3 |
| 11 |    23 |          4 |         3 |
+----+-------+------------+-----------+
8 rows in set (0.00 sec)
# 使⽤NOT IN 可以查询除了"MySQL"或"Java"课程的成绩
mysql> select * from score where course_id not in (select id from course where
name = 'Java' or name = 'MySQL');
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
|  3 |    33 |          1 |         5 |
|  4 |    98 |          1 |         6 |
|  6 |  59.5 |          2 |         5 |
|  9 |    99 |          3 |         5 |
| 12 |    56 |          4 |         5 |
| 13 |    72 |          4 |         6 |
| 15 |    37 |          5 |         5 |
| 16 |    56 |          6 |         2 |
| 17 |    43 |          6 |         4 |
| 18 |    79 |          6 |         6 |
| 19 |    80 |          7 |         2 |
| 20 |    92 |          7 |         6 |
+----+-------+------------+-----------+
12 rows in set (0.00 sec)

5.4多列子查询

单⾏⼦查询和多⾏⼦查询都只返回⼀列数据,多列⼦查询中可以返回多个列的数据,外层查询与嵌套 的内层查询的列要匹配
⽰例:查询重复录⼊的分数
# 插⼊重复的分数:score, student_id, course_id列重复
mysql> insert into score(score, student_id, course_id) values
(70.5, 1, 1),(98.5, 1, 3),(60, 2, 1);
# ⼦查询中返回多个列
mysql> SELECT * FROM score WHERE (score, student_id, course_id ) IN ( SELECT score, student_id,course_id FROM score GROUP BY score, student_id, course_id HAVINGcount( 0 ) > 1);+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
|  1 |  70.5 |          1 |         1 |
|  2 |  98.5 |          1 |         3 |
|  5 |    60 |          2 |         1 |
| 21 |  70.5 |          1 |         1 |
| 22 |  98.5 |          1 |         3 |
| 23 |    60 |          2 |         1 |
+----+-------+------------+-----------+
6 rows in set (0.00 sec)

5.5在from子句中使用子查询

当⼀个查询产⽣结果时,MySQL⾃动创建⼀个临时表,然后把结果集放在这个临时表中,最终返回 给⽤⼾,在from⼦句中也可以使⽤临时表进⾏⼦查询或表连接操作

 ⽰例:查询所有⽐"Java001班"平均分⾼的成绩信息

# ⾸先分步进⾏,第⼀步先查出Java001班的平均分
mysql> select avg(sc.score) score from student s join class c on s.class_id = c.id join score sc on s.id = sc.student_idwherec.name = 'Java001班';
+----------+
|    score |
+----------+
| 66.65625 |
+----------+
1 row in set (0.00 sec)
# 把以上查询做为临时表,与真实表进⾏⽐较
mysql> select * from score s, (select avg(sc.score) score from student s join class c on s.class_id = c.id join score sc on s.id = sc.student_idwherec.name = 'Java001班') tmp where s.score > tmp.score;
+----+-------+------------+-----------+----------+
| id | score | student_id | course_id |    score |
+----+-------+------------+-----------+----------+
|  1 |  70.5 |          1 |         1 | 66.65625 |
|  2 |  98.5 |          1 |         3 | 66.65625 |
|  4 |    98 |          1 |         6 | 66.65625 |
|  8 |    68 |          3 |         3 | 66.65625 |
|  9 |    99 |          3 |         5 | 66.65625 |
| 10 |    67 |          4 |         1 | 66.65625 |
| 13 |    72 |          4 |         6 | 66.65625 |
| 14 |    81 |          5 |         1 | 66.65625 |
| 18 |    79 |          6 |         6 | 66.65625 |
| 19 |    80 |          7 |         2 | 66.65625 |
| 20 |    92 |          7 |         6 | 66.65625 |
| 21 |  70.5 |          1 |         1 | 66.65625 |
| 22 |  98.5 |          1 |         3 | 66.65625 |
+----+-------+------------+-----------+----------+
13 rows in set (0.00 sec)
tmp 是临时表的别名

6.合并查询

在实际应⽤中,为了合并多个select操作返回的结果,可以使⽤集合操作符 union,union all

6.1创建新表并初始化数据

# 创建⼀个新表并初始化数据
mysql> create table student1 like student;
Query OK, 0 rows affected (0.03 sec)insert into student1 (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);
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings:mysql> select * from student1;
+----+-----------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+-----------+--------+------+--------+-------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 刘备 | 300001 | 18 | 1 | 1993-09-01 | 3 |
| 3 | 张⻜ | 300002 | 18 | 1 | 1993-09-01 | 3 |
| 4 | 关⽻ | 300003 | 18 | 1 | 1993-09-01 | 3 |
+----+-----------+--------+------+--------+-------------+----------+
4 rows in set (0.00 sec)

6.2Union

该操作符⽤于取得两个结果集的并集。当使⽤该操作符时,会⾃动去掉结果集中的重复⾏。
⽰例:查询student表中 id < 3 的同学和student1表中的所有同学
# 结果集中有两张表中的数据,但是唐三藏只返回了⼀条记录
mysql> select * from student where id < 3 union select * from student1;
+----+-----------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+-----------+--------+------+--------+-------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 刘备 | 300001 | 18 | 1 | 1993-09-01 | 3 |
| 3 | 张⻜ | 300002 | 18 | 1 | 1993-09-01 | 3 |
| 4 | 关⽻ | 300003 | 18 | 1 | 1993-09-01 | 3 |
+----+-----------+--------+------+--------+-------------+----------+
5 rows in set (0.00 sec)

6.3 Union all

该操作符⽤于取得两个结果集的并集。当使⽤该操作符时,不会去掉结果集中的重复⾏。
# 结果集中有两张表中的数据,返回了所有唐三藏的记录
mysql> select * from student where id < 3 union all select * from student1;
+----+-----------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+-----------+--------+------+--------+-------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 刘备 | 300001 | 18 | 1 | 1993-09-01 | 3 |
| 3 | 张⻜ | 300002 | 18 | 1 | 1993-09-01 | 3 |
| 4 | 关⽻ | 300003 | 18 | 1 | 1993-09-01 | 3 |
+----+-----------+--------+------+--------+-------------+----------+
6 rows in set (0.00 sec)

7.插入查询结果

7.1语法

INSERT INTO table_name [(column [, column ...])] SELECT ...

7.2示例

将student表中C++001班的学⽣复制到student1表中
mysql> insert into student1 (name, sno, age, gender, enroll_date, class_id)select s.name, s.sno, s.age, s.gender, s.enroll_date, s.class_idfrom student s, class c where s.class_id = c.id and c.name = 'C++001班';Query OK, 4 rows affected (0.01 sec)Records: 4 Duplicates: 0 Warnings: 0mysql> select * from student1;+----+--------------+--------+------+--------+-------------+----------+| id | name | sno | age | gender | enroll_date | class_id |+----+--------------+--------+------+--------+-------------+----------+| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 || 2 | 刘备 | 300001 | 18 | 1 | 1993-09-01 | 3 || 3 | 张⻜ | 300002 | 18 | 1 | 1993-09-01 | 3 || 4 | 关⽻ | 300003 | 18 | 1 | 1993-09-01 | 3 || 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 || 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 || 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 || 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |+----+--------------+--------+------+--------+-------------+----------+8 rows in set (0.00 sec

相关文章:

MySQL-联合查询

1.简介 1.1为什么要使用联合查询 在数据设计时由于范式的要求&#xff0c;数据被拆分到多个表中&#xff0c;那么要查询⼀个条数据的完整信息&#xff0c;就 要从多个表中获取数据&#xff0c;如下图所⽰&#xff1a;要获取学⽣的基本信息和班级信息就要从学⽣表和班级表中获…...

突触可塑性与STDP:神经网络中的自我调整机制

突触可塑性与STDP&#xff1a;神经网络中的自我调整机制 在神经网络的学习过程中&#xff0c;突触可塑性&#xff08;Synaptic Plasticity&#xff09;是指神经元之间的连接强度&#xff08;突触权重&#xff09;随着时间的推移而动态变化的能力。这种调整机制使神经网络能够通…...

【小沐学GIS】QGIS导出OpenStreetMap数据(QuickOSM、OSM)

文章目录 1、简介1.1 OSM1.2 QuickOSM1.3 Overpass Turbo 2、插件安装3、插件使用3.1 快速查询&#xff08;boundary边界&#xff09;3.2 快速查询&#xff08;railway铁路&#xff09;3.3 快速查询&#xff08;boundaryadmin_level行政边界&#xff09;3.4 快速查询&#xff0…...

推荐一款强大的书签管理工具,让你的网址不在落灰

在信息爆炸的互联网时代&#xff0c;我们每天都会浏览大量的网页&#xff0c;收藏各种各样的网址。然而&#xff0c;随着时间的推移&#xff0c;这些杂乱无章的书签往往让我们感到头疼。别担心&#xff0c;今天我要向你推荐一款强大的书签管理工具&#xff0c;它将帮助你轻松整…...

Python 工具库每日推荐 【Matplotlib】

文章目录 引言Python数据可视化库的重要性今日推荐:Matplotlib工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例:数据分析可视化案例分析高级特性自定义样式动画效果3D绘图性能优化技巧扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 T…...

在远程非桌面版Ubuntu中使用Qt5构建Hello World项目

在 Linux 下运行 Qt 应用程序&#xff0c;需要完成以下几个步骤&#xff0c;包括安装 Qt 工具、设置开发环境以及编译和运行项目。下面是详细的步骤&#xff1a; 1. 安装 Qt 1.1使用系统包管理器 sudo apt update 和 sudo apt install qt5-default qtcreator 命令用于更新 U…...

netty之基础aio,bio,nio

前言 在Java中&#xff0c;提供了一些关于使用IO的API&#xff0c;可以供开发者来读写外部数据和文件&#xff0c;我们称这些API为Java IO。IO是Java中比较重要知识点&#xff0c;且比较难学习的知识点。并且随着Java的发展为提供更好的数据传输性能&#xff0c;目前有三种IO共…...

在找工作吗?给你一个AI虚拟面试官助力你提前准备面试

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 让AI点亮我们的生活&#xff0c;是Shelly对…...

@KafkaListener注解中containerFactory属性的作用

在使用Spring Kafka时&#xff0c;containerFactory 属性是 KafkaListener 注解中的一个选项&#xff0c;它允许你指定一个 ContainerFactory Bean 的名称。这个 ContainerFactory 负责创建和管理 Kafka 消息监听容器。 以下是 containerFactory 属性的一些关键作用&#xff1…...

1006C简单题(计数式子的组合意义 + dp式子联立)

http://cplusoj.com/d/senior/p/SS241006C 对于这个式子&#xff0c;我们可以从它的组合意义入手。 假设我们有 n 1 n1 n1 个白球要染色&#xff0c;中间有一个绿球&#xff0c;绿球左边有 a a a 个红球&#xff0c;右边有 b b b 球。染完后绿球左边每个白球有 x x x 的贡…...

千益畅行,旅游创业新模式的创新与发展

旅游创业的时代背景与旅游卡的崛起&#xff0c;在当今快节奏的时代&#xff0c;旅行成为人们生活中的重要部分&#xff0c;随着科技发展和市场需求的变化&#xff0c;旅游创业项目中的旅游卡应运而生。 其中&#xff0c;“千益畅行” 旅游卡作为新兴力量&#xff0c;在共享经济…...

单调栈day54|42. 接雨水(高频面试题)、84. 柱状图中最大的矩形、两道题思维导图的汇总与对比

单调栈day54|42. 接雨水&#xff08;高频面试题&#xff09;、84. 柱状图中最大的矩形、两道题思维导图的汇总与对比 42. 接雨水84. 柱状图中最大的矩形两道题思维导图的汇总与对比 42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱…...

关于Excel将列号由字母改为数字

将Excel的列表由字母改为数字 步骤&#xff1a; 文件-选项-公式-勾选“使用公式”中的“R1C1引用样式(R)”-确定即可 部分步骤图示 设置前的样子 设置后的样子 虽然现在还不清楚在xlwings操作Excel时有什么作用&#xff0c;先留着吧。...

曾黎第二次受邀巴黎时装周看秀 为新疆棉代言引人瞩目

近日&#xff0c;演员曾黎受邀出席巴黎时装周Stella McCartney 2025春夏大秀&#xff0c;她身穿品牌25早春“超季”新装登场&#xff0c;干练的摩登蓝色西服&#xff0c;自信优雅&#xff0c;温婉大气&#xff0c;手提链条黑包上面绑着的一朵新疆棉花十分抢眼&#xff0c;成为全…...

No.6 笔记 | Linux操作系统基础:全面概览与核心要点

1. 简介与历史 1.1 起源 创始人&#xff1a;Linus Torvalds&#xff08;芬兰赫尔辛基大学学生&#xff09;初衷&#xff1a;设计一个替代Minix的全功能Unix操作系统首次发布&#xff1a;1991年10月5日&#xff0c;Linux v0.01版本 2. Linux特点 多用户多任务&#xff1a;用…...

MySQL之分库分表后带来的“副作用”你是怎么解决的?

目录标题 一、垂直分表后带来的隐患二、水平分表后带来的问题1.多表联查问题2.增删改数据问题3.聚合操作问题 三、垂直分库后产生的问题1.跨库join问题2.分布式事务问题3.部分业务库依然存在的性能问题 四、水平分库后需要解决的问题1.聚合操作和连表问题2.数据分页问题3.ID主键…...

【Python】Python-JOSE:Python 中的 JSON Web Token 处理库

Python-JOSE 是一个用于处理 JSON Web Token (JWT) 和 JOSE (JSON Object Signing and Encryption) 标准的 Python 库。它支持对 JWT 进行签名、加密、解密和验证等操作&#xff0c;是处理基于 OAuth 2.0 和 OpenID Connect 协议的身份验证和授权任务的理想选择。Python-JOSE 实…...

SpringBoot3+Druid YAML配置

背景 Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生&#xff0c;内置强大的监控功能&#xff0c;监控特性不影响性能。功能强大&#xff0c;能防SQL注入&#xff0c;内置Loging能诊断Hack应用行为。现在已经SpringBoot3&#xff0c;Druid的配置也需要随…...

【c语言——指针详解(3)】

文章目录 一、字符指针变量二、数组指针变量1、 数组指针变量是什么&#xff1f;2、 数组指针变量怎么初始化 三、⼆维数组传参的本质四、函数指针变量1、函数指针变量的创建2、函数指针变量的使⽤3、两段有趣的代码1&#xff09;typedef 关键字2&#xff09;typedef和define的…...

QT系统学习篇(2)- Qt跨平台GUI原理机制

一、Qt工程管理 1、新建项目&#xff1a; 我们程序员新建项目对话框所有5类项目模板 Application: Qt的应用程序&#xff0c;包含Qt Quick和普通窗口程序。 Library: 它可以创建动态库、静态库、Qt Creator自身插件、Qt Quick扩展插件。 其他项目: 创建单元测试项目、子目录项…...

运用MinIO技术服务器实现文件上传——在Linux系统上安装和启动(一)

# MinIO 单机版环境搭建详解 ## 1. 简介 随着大数据时代的到来&#xff0c;数据存储的需求日益增大&#xff0c;如何有效地存储和管理大规模的非结构化数据成为许多企业和开发者面临的挑战。MinIO 作为一个高性能、分布式对象存储系统&#xff0c;致力于为用户提供简单、快速…...

Python技术深度探索:从基础到进阶的实践之旅(第一篇)

Python技术深度探索&#xff1a;从基础到进阶的实践之旅&#xff08;第一篇&#xff09; 在编程的世界里&#xff0c;Python以其简洁的语法、强大的库支持和广泛的应用领域&#xff0c;成为了无数开发者心中的“瑞士军刀”。无论是数据分析、机器学习、Web开发&#xff0c;还是…...

利士策分享,旅游是否要舟车劳顿才能尽兴?

利士策分享&#xff0c;旅游是否要舟车劳顿才能尽兴&#xff1f; 国庆假期&#xff0c;当夜幕降临&#xff0c;城市灯火阑珊&#xff0c;一场关于美食与等待的较量悄然上演。 李女士在北京天坛公园附近餐厅的等位经历——前方1053桌的壮观景象&#xff0c;不仅让人咋舌&#xf…...

C++入门——类的默认成员函数(取地址运算符重载)

文章目录 一、const成员函数二、取地址运算符重载总结 一、const成员函数 1.将const修饰的成员函数称之为const成员函数&#xff0c;const修饰成员函数放到成员函数参数列表的后⾯。2.const实际修饰该成员函数隐含的this指针&#xff0c;表明在该成员函数中不能对类的任何成员进…...

学习记录:js算法(四十九):二叉树的层序遍历

文章目录 二叉树的层序遍历网上思路队列循环 总结 二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 图一&#xff1a; 示例 1&#xff1a;如图一 输入&#xff1a;roo…...

【PCB工艺】表面贴装技术中常见错误

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 1、什么是SMT和SMD2、表面贴装技术的优势是什么&#xff1f;3、通孔和表面贴装技术之间的区别是什么&#xff1f;4、焊…...

3.使用条件语句编写存储过程(3/10)

引言 在现代数据库管理系统中&#xff0c;存储过程扮演着至关重要的角色。它们是一组为了执行特定任务而编写的SQL语句&#xff0c;这些语句被保存在数据库中&#xff0c;可以被重复调用。存储过程不仅可以提高数据库操作的效率&#xff0c;还可以增强数据的安全性和一致性。此…...

Effective C++中文版学习记录(三)

Effective C中文版学习记录&#xff08;三&#xff09; 章节三&#xff1a;资源管理 进度&#xff1a;17/55 文章目录 Effective C中文版学习记录&#xff08;三&#xff09;条款13、以对象管理资源条款14、在资源管理类中小心copying行为条款15、在资源管理类中提供对原始资…...

VBA学习(76):文件合并神器/代码

1.定义变量 Dim savePath As String Dim SaveFile As String Dim dataFolder As String Dim FileSystem As Object Dim folder As Object Dim FileExtn As String Dim t As Integer Dim blnCkb As Boolean 2.自定保存文件名、选择待合并文件所在文件夹 Private Sub CkbName_…...

非农就业数据超预期,美联储降息步伐或放缓?

KlipC报道&#xff1a;当地时间10月4日&#xff0c;美国劳工部发布了最新的非农就业数据。数据显示&#xff0c;9月非农就业人数增加25.4万人&#xff0c;远超市场预期。失业率为4.1%&#xff0c;比上月略降0.1个百分点。平均时薪环比增长0.4%&#xff0c;亦高于市场预期。此外…...