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.外连接
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应用场景
# 不为表指定别名
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表连接练习
# 相关的表全部加⼊连接,并确定连接条件
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.子查询
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多行子查询
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)
6.合并查询
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
# 结果集中有两张表中的数据,但是唐三藏只返回了⼀条记录
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示例
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