文章目录
- 1. 简介
- 1.1 为什么要使用联合查询
- 1.2 多表联合查询时MySQL内部是如何进行计算的
- 2. 内连接
- 2.1 语法
- 2.2 示例
- 3. 外连接
- 3.1 语法
- 3.2 示例
- 4. 自连接
- 4.1 应用场景
- 4.2 示例
- 4.3 表连接练习
- 5. 子查询
- 5.1 语法
- 5.2 单行子查询
- 5.3 多行子查询
- 5.4 多列子查询
- 5.5 在from 子句中使用子查询
- 6. 合并查询
- 6.1 Union
- 6.2 Union all
- 7. 插入查询结果
- 7.1 语法
- 7.2 示例
1. 简介
1.1 为什么要使用联合查询
在数据库设计时由于范式的要求,数据被拆分到多个表中,那么要查询一个条数据的完整信息,就要从多个表中获取数据,如下图所示:要获取学生的基本信息和班级信息就要从学生表和班级表中获取,这时就需要使用联合查询,这里的联合指的是多个表的组合。
一次查询涉及到两个或者两个以上的表,就称为联合查询。
1.2 多表联合查询时MySQL内部是如何进行计算的
-- 创建学生表
mysql> drop table if exists student;
Query OK, 0 rows affected (0.03 sec)mysql> create table student(-> id bigint primary key auto_increment,-> name varchar(20) not null,-> sno varchar(10) not null,-> age int,-> gender tinyint(1),-> enroll_date date,-> class_id bigint not null-> );
Query OK, 0 rows affected, 1 warning (0.02 sec)
-- 插入学生数据
mysql> 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);
Query OK, 8 rows affected (0.05 sec)
Records: 8 Duplicates: 0 Warnings: 0mysql> select * from student;
+----+----------+--------+------+--------+-------------+----------+
| 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 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
| 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.03 sec)-- 创建课程表
mysql> drop table if exists class;
Query OK, 0 rows affected (0.05 sec)mysql> create table class (-> id bigint primary key auto_increment,-> name varchar(20) not null-> );
Query OK, 0 rows affected (0.02 sec)
-- 插入课程数据
mysql> insert into class(name) values ('Java001班'), ('C++001班'), ('前端001班');
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0mysql> select * from class;
+----+-----------+
| id | name |
+----+-----------+
| 1 | Java001班 |
| 2 | C++001班 |
| 3 | 前端001班 |
+----+-----------+
3 rows in set (0.00 sec)
- 参与查询的所有表取笛卡尔积(全排列),结果集存放在临时表中。
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 | 2 | 3 | 前端001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 1 | Java001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 3 | 前端001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 1 | Java001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 3 | 前端001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 1 | Java001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 3 | 前端001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 1 | Java001班 |
+----+----------+--------+------+--------+-------------+----------+----+-----------+
24 rows in set (0.00 sec)
- 观察哪些记录是有效数据,根据两个表的关联关系过滤掉无效数据。
-- where条件不能写成class_id = id,class_id在student表中,但是两张表中都有id列,不指定表名时,MySQL无法分清要使用那张表中的id列。
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 | 2 | 2 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
+----+----------+--------+------+--------+-------------+----------+----+-----------+
8 rows in set (0.00 sec)
如果联合查询表的个数越多,表中的数据量越大,临时表就会越大,所以根据实际情况确定联合查询表的个数。
- 通过指定列查询,精简查询结果
mysql> select student.id,-> student.name,-> student.sno,-> student.age,-> student.gender,-> student.enroll_date,-> class.name-> from student, class-> where student.class_id = class.id;
+----+----------+--------+------+--------+-------------+-----------+
| id | name | sno | age | gender | enroll_date | name |
+----+----------+--------+------+--------+-------------+-----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | Java001班 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | Java001班 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | Java001班 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | Java001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | C++001班 |
+----+----------+--------+------+--------+-------------+-----------+
8 rows in set (0.00 sec)
- 通过给表起别名的方式来精简查询sql语句
mysql> select s.id, s.name, s.sno, s.age, s.gender, s.enroll_date, c.name from student s, class c where s.class_id = c.id;
+----+----------+--------+------+--------+-------------+-----------+
| id | name | sno | age | gender | enroll_date | name |
+----+----------+--------+------+--------+-------------+-----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | Java001班 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | Java001班 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | Java001班 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | Java001班 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | C++001班 |
+----+----------+--------+------+--------+-------------+-----------+
8 rows in set (0.00 sec)
2. 内连接
2.1 语法
简写:
select 字段 from 表1 别名1, 表2 别名2 where 连接条件 and 其他条件;
mysql> select * from student s, class c where s.class_id = c.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 | 2 | 2 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
+----+----------+--------+------+--------+-------------+----------+----+-----------+
8 rows in set (0.00 sec)
规范写法:
select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 where 其他条件;
mysql> select * from student s join class c on s.class_id = c.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 | 2 | 2 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
+----+----------+--------+------+--------+-------------+----------+----+-----------+
8 rows in set (0.00 sec)mysql> select * from student s inner join class c on s.class_id = c.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 | 2 | 2 | C++001班 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | C++001班 |
+----+----------+--------+------+--------+-------------+----------+----+-----------+
8 rows in set (0.00 sec)
- join两边肯定是表名
- on后面肯定是条件
2.2 示例
- 查询唐三藏同学的成绩
-- 创建成绩表
mysql> drop table if exists score;
Query OK, 0 rows affected, 1 warning (0.00 sec)mysql> create table score (-> id bigint primary key auto_increment,-> student_id bigint not null,-> course_id bigint not null,-> score float not null-> );
Query OK, 0 rows affected (0.02 sec)mysql> 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);
Query OK, 20 rows affected (0.01 sec)
Records: 20 Duplicates: 0 Warnings: 0mysql> select * from score;
+----+------------+-----------+-------+
| id | student_id | course_id | score |
+----+------------+-----------+-------+
| 1 | 1 | 1 | 70.5 |
| 2 | 1 | 3 | 98.5 |
| 3 | 1 | 5 | 33 |
| 4 | 1 | 6 | 98 |
| 5 | 2 | 1 | 60 |
| 6 | 2 | 5 | 59.5 |
| 7 | 3 | 1 | 33 |
| 8 | 3 | 3 | 68 |
| 9 | 3 | 5 | 99 |
| 10 | 4 | 1 | 67 |
| 11 | 4 | 3 | 23 |
| 12 | 4 | 5 | 56 |
| 13 | 4 | 6 | 72 |
| 14 | 5 | 1 | 81 |
| 15 | 5 | 5 | 37 |
| 16 | 6 | 2 | 56 |
| 17 | 6 | 4 | 43 |
| 18 | 6 | 6 | 79 |
| 19 | 7 | 2 | 80 |
| 20 | 7 | 6 | 92 |
+----+------------+-----------+-------+
20 rows in set (0.00 sec)
- 取两张表的笛卡尔积
mysql> select * from student, score;
+----+----------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
| id | name | sno | age | gender | enroll_date | class_id | id | student_id | course_id | score |
+----+----------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 1 | 1 | 1 | 70.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 1 | 1 | 1 | 70.5 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 1 | 1 | 1 | 70.5 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 1 | 1 | 1 | 70.5 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | 1 | 3 | 98.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | 1 | 3 | 98.5 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 2 | 1 | 3 | 98.5 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 2 | 1 | 3 | 98.5 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 3 | 1 | 5 | 33 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 3 | 1 | 5 | 33 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 3 | 1 | 5 | 33 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 3 | 1 | 5 | 33 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 4 | 1 | 6 | 98 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 4 | 1 | 6 | 98 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 4 | 1 | 6 | 98 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 4 | 1 | 6 | 98 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 5 | 2 | 1 | 60 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 5 | 2 | 1 | 60 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 5 | 2 | 1 | 60 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 5 | 2 | 1 | 60 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 5 | 2 | 1 | 60 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 5 | 2 | 1 | 60 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 5 | 2 | 1 | 60 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 5 | 2 | 1 | 60 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 6 | 2 | 5 | 59.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 6 | 2 | 5 | 59.5 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 6 | 2 | 5 | 59.5 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 6 | 2 | 5 | 59.5 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 6 | 2 | 5 | 59.5 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 6 | 2 | 5 | 59.5 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 6 | 2 | 5 | 59.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 6 | 2 | 5 | 59.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 7 | 3 | 1 | 33 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 7 | 3 | 1 | 33 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 7 | 3 | 1 | 33 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 7 | 3 | 1 | 33 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 7 | 3 | 1 | 33 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 7 | 3 | 1 | 33 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 7 | 3 | 1 | 33 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 7 | 3 | 1 | 33 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 8 | 3 | 3 | 68 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 8 | 3 | 3 | 68 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 8 | 3 | 3 | 68 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 8 | 3 | 3 | 68 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 8 | 3 | 3 | 68 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 8 | 3 | 3 | 68 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 8 | 3 | 3 | 68 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 8 | 3 | 3 | 68 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 9 | 3 | 5 | 99 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 9 | 3 | 5 | 99 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 9 | 3 | 5 | 99 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 9 | 3 | 5 | 99 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 9 | 3 | 5 | 99 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 9 | 3 | 5 | 99 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 9 | 3 | 5 | 99 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 9 | 3 | 5 | 99 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 10 | 4 | 1 | 67 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 10 | 4 | 1 | 67 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 10 | 4 | 1 | 67 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 10 | 4 | 1 | 67 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 10 | 4 | 1 | 67 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 10 | 4 | 1 | 67 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 10 | 4 | 1 | 67 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 10 | 4 | 1 | 67 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 11 | 4 | 3 | 23 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 11 | 4 | 3 | 23 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 11 | 4 | 3 | 23 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 11 | 4 | 3 | 23 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 11 | 4 | 3 | 23 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 11 | 4 | 3 | 23 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 11 | 4 | 3 | 23 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 11 | 4 | 3 | 23 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 12 | 4 | 5 | 56 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 12 | 4 | 5 | 56 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 12 | 4 | 5 | 56 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 12 | 4 | 5 | 56 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 12 | 4 | 5 | 56 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 12 | 4 | 5 | 56 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 12 | 4 | 5 | 56 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 12 | 4 | 5 | 56 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 13 | 4 | 6 | 72 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 13 | 4 | 6 | 72 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 13 | 4 | 6 | 72 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 13 | 4 | 6 | 72 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 13 | 4 | 6 | 72 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 13 | 4 | 6 | 72 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 13 | 4 | 6 | 72 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 13 | 4 | 6 | 72 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 14 | 5 | 1 | 81 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 14 | 5 | 1 | 81 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 14 | 5 | 1 | 81 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 14 | 5 | 1 | 81 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 14 | 5 | 1 | 81 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 14 | 5 | 1 | 81 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 14 | 5 | 1 | 81 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 14 | 5 | 1 | 81 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 15 | 5 | 5 | 37 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 15 | 5 | 5 | 37 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 15 | 5 | 5 | 37 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 15 | 5 | 5 | 37 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 15 | 5 | 5 | 37 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 15 | 5 | 5 | 37 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 15 | 5 | 5 | 37 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 15 | 5 | 5 | 37 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 16 | 6 | 2 | 56 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 16 | 6 | 2 | 56 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 16 | 6 | 2 | 56 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 16 | 6 | 2 | 56 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 16 | 6 | 2 | 56 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 16 | 6 | 2 | 56 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 16 | 6 | 2 | 56 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 16 | 6 | 2 | 56 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 17 | 6 | 4 | 43 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 17 | 6 | 4 | 43 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 17 | 6 | 4 | 43 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 17 | 6 | 4 | 43 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 17 | 6 | 4 | 43 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 17 | 6 | 4 | 43 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 17 | 6 | 4 | 43 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 17 | 6 | 4 | 43 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 18 | 6 | 6 | 79 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 18 | 6 | 6 | 79 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 18 | 6 | 6 | 79 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 18 | 6 | 6 | 79 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 18 | 6 | 6 | 79 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 18 | 6 | 6 | 79 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 18 | 6 | 6 | 79 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 18 | 6 | 6 | 79 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 19 | 7 | 2 | 80 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 19 | 7 | 2 | 80 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 19 | 7 | 2 | 80 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 19 | 7 | 2 | 80 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 19 | 7 | 2 | 80 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 19 | 7 | 2 | 80 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 19 | 7 | 2 | 80 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 19 | 7 | 2 | 80 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 20 | 7 | 6 | 92 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 20 | 7 | 6 | 92 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 20 | 7 | 6 | 92 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 20 | 7 | 6 | 92 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 20 | 7 | 6 | 92 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 20 | 7 | 6 | 92 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 20 | 7 | 6 | 92 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 20 | 7 | 6 | 92 |
+----+----------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
160 rows in set (0.00 sec)
- 根据表与表之间的关系,确定过滤条件
mysql> select * from student s, score sco where s.id = sco.student_id and s.name = '唐三藏';
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
| id | name | sno | age | gender | enroll_date | class_id | id | student_id | course_id | score |
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 |
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
4 rows in set (0.00 sec)
- 精简sql语句
mysql> select s.id, s.name, sco.score from student s, score sco where s.id = sco.student_id and s.name = '唐三藏';
+----+--------+-------+
| id | name | score |
+----+--------+-------+
| 1 | 唐三藏 | 70.5 |
| 1 | 唐三藏 | 98.5 |
| 1 | 唐三藏 | 33 |
| 1 | 唐三藏 | 98 |
+----+--------+-------+
4 rows in set (0.00 sec)
- 查询所有同学的总成绩,以及同学的个人信息
mysql> select * from student s, score sco where s.id = sco.student_id;
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
| id | name | sno | age | gender | enroll_date | class_id | id | student_id | course_id | score |
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 5 | 2 | 1 | 60 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 6 | 2 | 5 | 59.5 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 7 | 3 | 1 | 33 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 8 | 3 | 3 | 68 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 9 | 3 | 5 | 99 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 10 | 4 | 1 | 67 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 11 | 4 | 3 | 23 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 12 | 4 | 5 | 56 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 13 | 4 | 6 | 72 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 14 | 5 | 1 | 81 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 15 | 5 | 5 | 37 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 16 | 6 | 2 | 56 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 17 | 6 | 4 | 43 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 18 | 6 | 6 | 79 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 19 | 7 | 2 | 80 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 20 | 7 | 6 | 92 |
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+
20 rows in set (0.00 sec)
mysql> select s.id, s.name, s.age, sum(sco.score) from student s, score sco where s.id = sco.student_id group by (sco.student_id);
+----+--------+------+----------------+
| id | name | age | sum(sco.score) |
+----+--------+------+----------------+
| 1 | 唐三藏 | 18 | 300 |
| 2 | 孙悟空 | 18 | 119.5 |
| 3 | 猪悟能 | 18 | 200 |
| 4 | 沙悟净 | 18 | 218 |
| 5 | 宋江 | 18 | 118 |
| 6 | 武松 | 18 | 178 |
| 7 | 李逹 | 18 | 172 |
+----+--------+------+----------------+
7 rows in set (0.01 sec)
- 查询所有同学每门课的成绩,以及同学的个人信息
创建课程表
mysql> drop table if exists course;
Query OK, 0 rows affected (0.02 sec)mysql> create table course (-> id bigint primary key auto_increment,-> name varchar(20) not null-> );
Query OK, 0 rows affected (0.04 sec)mysql> insert into course (name) values ('Java'), ('C++'), ('MySQL'), ('操作系统'), ('计算机网络'), ('数据结构');
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0mysql> select * from course;
+----+------------+
| id | name |
+----+------------+
| 1 | Java |
| 2 | C++ |
| 3 | MySQL |
| 4 | 操作系统 |
| 5 | 计算机网络 |
| 6 | 数据结构 |
+----+------------+
6 rows in set (0.00 sec)
- 取笛卡尔积(这里共有960条,只截取部分)
mysql> select * from student, course, score;
+----+----------+--------+------+--------+-------------+----------+----+------------+----+------------+-----------+-------+
| id | name | sno | age | gender | enroll_date | class_id | id | name | id | student_id | course_id | score |
+----+----------+--------+------+--------+-------------+----------+----+------------+----+------------+-----------+-------+
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 1 | Java | 1 | 1 | 1 | 70.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 2 | C++ | 1 | 1 | 1 | 70.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 3 | MySQL | 1 | 1 | 1 | 70.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 4 | 操作系统 | 1 | 1 | 1 | 70.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 5 | 计算机网络 | 1 | 1 | 1 | 70.5 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | 6 | 数据结构 | 1 | 1 | 1 | 70.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 1 | Java | 1 | 1 | 1 | 70.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 2 | C++ | 1 | 1 | 1 | 70.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 3 | MySQL | 1 | 1 | 1 | 70.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 4 | 操作系统 | 1 | 1 | 1 | 70.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 5 | 计算机网络 | 1 | 1 | 1 | 70.5 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 6 | 数据结构 | 1 | 1 | 1 | 70.5 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 1 | Java | 20 | 7 | 6 | 92 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 2 | C++ | 20 | 7 | 6 | 92 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 3 | MySQL | 20 | 7 | 6 | 92 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 4 | 操作系统 | 20 | 7 | 6 | 92 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 5 | 计算机网络 | 20 | 7 | 6 | 92 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 6 | 数据结构 | 20 | 7 | 6 | 92 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | Java | 20 | 7 | 6 | 92 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 2 | C++ | 20 | 7 | 6 | 92 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 3 | MySQL | 20 | 7 | 6 | 92 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 4 | 操作系统 | 20 | 7 | 6 | 92 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 5 | 计算机网络 | 20 | 7 | 6 | 92 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 6 | 数据结构 | 20 | 7 | 6 | 92 |
+----+----------+--------+------+--------+-------------+----------+----+------------+----+------------+-----------+-------+
960 rows in set (0.00 sec)
- 查看表结构,确认表连接的条件
mysql> desc student;
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
| sno | varchar(10) | NO | | NULL | |
| age | int | YES | | NULL | |
| gender | tinyint(1) | YES | | NULL | |
| enroll_date | date | YES | | NULL | |
| class_id | bigint | NO | | NULL | |
+-------------+-------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)mysql> desc score;
+------------+--------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| student_id | bigint | NO | | NULL | |
| course_id | bigint | NO | | NULL | |
| score | float | NO | | NULL | |
+------------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)mysql> desc course;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
- 添加过滤条件
mysql> select * from student s, score sco, course c where s.id = sco.student_id and c.id = sco.course_id;
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+----+------------+
| id | name | sno | age | gender | enroll_date | class_id | id | student_id | course_id | score | id | name |
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+----+------------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 | 1 | Java |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 | 3 | MySQL |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 | 5 | 计算机网络 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 | 6 | 数据结构 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 5 | 2 | 1 | 60 | 1 | Java |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 6 | 2 | 5 | 59.5 | 5 | 计算机网络 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 7 | 3 | 1 | 33 | 1 | Java |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 8 | 3 | 3 | 68 | 3 | MySQL |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 9 | 3 | 5 | 99 | 5 | 计算机网络 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 10 | 4 | 1 | 67 | 1 | Java |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 11 | 4 | 3 | 23 | 3 | MySQL |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 12 | 4 | 5 | 56 | 5 | 计算机网络 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 13 | 4 | 6 | 72 | 6 | 数据结构 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 14 | 5 | 1 | 81 | 1 | Java |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 15 | 5 | 5 | 37 | 5 | 计算机网络 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 16 | 6 | 2 | 56 | 2 | C++ |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 17 | 6 | 4 | 43 | 4 | 操作系统 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 18 | 6 | 6 | 79 | 6 | 数据结构 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 19 | 7 | 2 | 80 | 2 | C++ |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 20 | 7 | 6 | 92 | 6 | 数据结构 |
+----+--------+--------+------+--------+-------------+----------+----+------------+-----------+-------+----+------------+
20 rows in set (0.01 sec)
- 精简查询字段,得到最终结果
mysql> select s.*, c.name, sco.score from student s, score sco, course c where s.id = sco.student_id and c.id = sco.course_id;
+----+--------+--------+------+--------+-------------+----------+------------+-------+
| id | name | sno | age | gender | enroll_date | class_id | name | score |
+----+--------+--------+------+--------+-------------+----------+------------+-------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | Java | 70.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | MySQL | 98.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 计算机网络 | 33 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 数据结构 | 98 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | Java | 60 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 计算机网络 | 59.5 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | Java | 33 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | MySQL | 68 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 计算机网络 | 99 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | Java | 67 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | MySQL | 23 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 计算机网络 | 56 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 数据结构 | 72 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | Java | 81 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 计算机网络 | 37 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | C++ | 56 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 操作系统 | 43 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 数据结构 | 79 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | C++ | 80 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 数据结构 | 92 |
+----+--------+--------+------+--------+-------------+----------+------------+-------+
20 rows in set (0.00 sec)
在工作中尽量少做大量的表关联查询,有些公司也规定,一般表关联查询不超过三张表。
3. 外连接
外连接分为左外连接、右外连接和全外来连接 三种类型,MySQL不支持全外连接。
- 左外连接:返回左表的所有记录和右表中匹配的记录。如果右表中没有匹配的记录,则结果集中对应的字段会显示null。
- 右外连接:与左外连接相反,返回右表的所有记录和左表中匹配的记录。如果左表中没有匹配的记录,则结果集中对应字段会显示为null。
- 全外连接:结合了左外连接和右外连接的特点,返回左右表中的所有记录。如果某一边表中没有匹配的记录,则结果集中对应字段会显示为NULL。
3.1 语法
-- 左外连接(基表在left join 的左边)
select 字段名 from 表名1 left join 表名2 on 连接条件;
-- 右外连接(基表在right join的右边)
select 字段 from 表名1 right join 表名2 on 连接条件;
3.2 示例
- 查询没有参加考试的同学信息(左外连接为例)
mysql> select * from student s left join score sco on s.id = sco.student_id;
+----+----------+--------+------+--------+-------------+----------+------+------------+-----------+-------+
| id | name | sno | age | gender | enroll_date | class_id | id | student_id | course_id | score |
+----+----------+--------+------+--------+-------------+----------+------+------------+-----------+-------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 4 | 1 | 6 | 98 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 3 | 1 | 5 | 33 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 2 | 1 | 3 | 98.5 |
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 | 1 | 1 | 1 | 70.5 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 6 | 2 | 5 | 59.5 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 | 5 | 2 | 1 | 60 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 9 | 3 | 5 | 99 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 8 | 3 | 3 | 68 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 | 7 | 3 | 1 | 33 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 13 | 4 | 6 | 72 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 12 | 4 | 5 | 56 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 11 | 4 | 3 | 23 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 | 10 | 4 | 1 | 67 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 15 | 5 | 5 | 37 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 | 14 | 5 | 1 | 81 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 18 | 6 | 6 | 79 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 17 | 6 | 4 | 43 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 | 16 | 6 | 2 | 56 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 20 | 7 | 6 | 92 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 | 19 | 7 | 2 | 80 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | NULL | NULL | NULL | NULL |
+----+----------+--------+------+--------+-------------+----------+------+------------+-----------+-------+
21 rows in set (0.01 sec)
mysql> select * from student s left join score sco on s.id = sco.student_id where sco.id is null;
+----+----------+--------+------+--------+-------------+----------+------+------------+-----------+-------+
| id | name | sno | age | gender | enroll_date | class_id | id | student_id | course_id | score |
+----+----------+--------+------+--------+-------------+----------+------+------------+-----------+-------+
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 | NULL | NULL | NULL | NULL |
+----+----------+--------+------+--------+-------------+----------+------+------------+-----------+-------+
1 row in set (0.00 sec)mysql> select s.* from student s left join score sco on s.id = sco.student_id where sco.id is null;
+----+----------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+----------+--------+------+--------+-------------+----------+
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
+----+----------+--------+------+--------+-------------+----------+
1 row in set (0.00 sec)
- 查询没有学生的班级(右外连接为例)
mysql> select * from student s right join class c on s.class_id = c.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班 |
+------+----------+--------+------+--------+-------------+----------+----+-----------+
9 rows in set (0.00 sec)mysql> select c.* from student s right join class c on s.class_id = c.id where s.id is null;
+----+-----------+
| id | name |
+----+-----------+
| 3 | 前端001班 |
+----+-----------+
1 row in set (0.00 sec)
最终MySQL在执行右外连接时,会把它转换为左外连接。
4. 自连接
4.1 应用场景
自连接是自己与自己取笛卡尔积,可以把行转化成列,在查询的时候可以使用where条件对结果进行过滤,或者说实现行与行之间的比较。在做表连接时为表起不同的别名。
-- 不为表起别名(不能正常查询)
mysql> select * from score, score;
ERROR 1066 (42000): Not unique table/alias: 'score'
-- 为表起别名(可以正常查询)select * from score sco1, score sco2;
4.2 示例
- 显示所有“MySQL”成绩比“Java”成绩高的成绩信息
mysql> select * from score s1, score s2 where s1.student_id = s2.student_id and s1.course_id = 1 and s2.course_id = 3 and s2.score > s1.score;
+----+------------+-----------+-------+----+------------+-----------+-------+
| id | student_id | course_id | score | id | student_id | course_id | score |
+----+------------+-----------+-------+----+------------+-----------+-------+
| 1 | 1 | 1 | 70.5 | 2 | 1 | 3 | 98.5 |
| 7 | 3 | 1 | 33 | 8 | 3 | 3 | 68 |
+----+------------+-----------+-------+----+------------+-----------+-------+
2 rows in set (0.01 sec)mysql> select s1.student_id, s1.score 'Java分数', s2.score 'MySQL分数' from score s1, score s2 where s1.student_id = s2.student_id and s1.course_id = 1 and s2.course_id = 3 and s2.score > s1.score;
+------------+----------+-----------+
| student_id | Java分数 | MySQL分数 |
+------------+----------+-----------+
| 1 | 70.5 | 98.5 |
| 3 | 33 | 68 |
+------------+----------+-----------+
2 rows in set (0.00 sec)
4.3 表连接练习
- 显示所有"MySQL"成绩 比“Java”成绩高的学生信息和班级以及成绩信息
select s.id, s.`name` '姓名', cla.name, s1.score 'mysql成绩', s2.score 'Java成绩'
from
score s1,
score s2,
student s,
class cla
where
s1.student_id = s2.student_id
and
s.id = s1.student_id
and
s.class_id = cla.id
and
s1.course_id = 3
and
s2.course_id = 1
and
s1.score > s2.score;
+----+--------+-----------+-----------+----------+
| id | 姓名 | name | mysql成绩 | Java成绩 |
+----+--------+-----------+-----------+----------+
| 1 | 唐三藏 | Java001班 | 98.5 | 70.5 |
| 3 | 猪悟能 | 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 class_id from student where name = '不想毕业';
+----------+
| class_id |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)mysql> select name from student where class_id = ( select class_id from student where name = '不想毕业');
+----------+
| name |
+----------+
| 宋江 |
| 武松 |
| 李逹 |
| 不想毕业 |
+----------+
4 rows in set (0.01 sec)mysql> select name from student where class_id = ( select class_id from student where name = '不想毕业') and name <> '不想毕业';
+------+
| name |
+------+
| 宋江 |
| 武松 |
| 李逹 |
+------+
3 rows in set (0.00 sec)
5.3 多行子查询
嵌套的查询中返回多行数据,使用[NOT]IN关键字
- 查询“MySQL”或“Java”课程的成绩信息
mysql> select * from course where name = 'MySQL' or name = 'Java';
+----+-------+
| id | name |
+----+-------+
| 1 | Java |
| 3 | MySQL |
+----+-------+
2 rows in set (0.00 sec)mysql> select * from score where course_id IN (select id from course where name = 'MySQL' or name = 'Java');
+----+------------+-----------+-------+
| id | student_id | course_id | score |
+----+------------+-----------+-------+
| 1 | 1 | 1 | 70.5 |
| 2 | 1 | 3 | 98.5 |
| 5 | 2 | 1 | 60 |
| 7 | 3 | 1 | 33 |
| 8 | 3 | 3 | 68 |
| 10 | 4 | 1 | 67 |
| 11 | 4 | 3 | 23 |
| 14 | 5 | 1 | 81 |
+----+------------+-----------+-------+
8 rows in set (0.01 sec)
- 查询除了“MySQL”和“Java”课程的成绩信息
mysql> select * from score where course_id NOT IN (select id from course where name = 'MySQL' or name = 'Java');
+----+------------+-----------+-------+
| id | student_id | course_id | score |
+----+------------+-----------+-------+
| 3 | 1 | 5 | 33 |
| 4 | 1 | 6 | 98 |
| 6 | 2 | 5 | 59.5 |
| 9 | 3 | 5 | 99 |
| 12 | 4 | 5 | 56 |
| 13 | 4 | 6 | 72 |
| 15 | 5 | 5 | 37 |
| 16 | 6 | 2 | 56 |
| 17 | 6 | 4 | 43 |
| 18 | 6 | 6 | 79 |
| 19 | 7 | 2 | 80 |
| 20 | 7 | 6 | 92 |
+----+------------+-----------+-------+
12 rows in set (0.01 sec)
5.4 多列子查询
单行子查询和多行子查询都只返回一列数据,多列子查询中可以返回多个列的数据,外层查询与嵌套查询的内层查询的列要匹配。
- 查询重复录入的分数
-- 插入重复的分数
mysql> insert into score(score, student_id, course_id) values (70.5, 1, 1), (98.5, 1, 3), (60, 2, 1);
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0mysql> select * from score order by student_id asc, score desc;
+----+------------+-----------+-------+
| id | student_id | course_id | score |
+----+------------+-----------+-------+
| 2 | 1 | 3 | 98.5 |
| 22 | 1 | 3 | 98.5 |
| 4 | 1 | 6 | 98 |
| 1 | 1 | 1 | 70.5 |
| 21 | 1 | 1 | 70.5 |
| 3 | 1 | 5 | 33 |
| 5 | 2 | 1 | 60 |
| 23 | 2 | 1 | 60 |
| 6 | 2 | 5 | 59.5 |
| 9 | 3 | 5 | 99 |
| 8 | 3 | 3 | 68 |
| 7 | 3 | 1 | 33 |
| 13 | 4 | 6 | 72 |
| 10 | 4 | 1 | 67 |
| 12 | 4 | 5 | 56 |
| 11 | 4 | 3 | 23 |
| 14 | 5 | 1 | 81 |
| 15 | 5 | 5 | 37 |
| 18 | 6 | 6 | 79 |
| 16 | 6 | 2 | 56 |
| 17 | 6 | 4 | 43 |
| 20 | 7 | 6 | 92 |
| 19 | 7 | 2 | 80 |
+----+------------+-----------+-------+
23 rows in set (0.00 sec)
- 对重复的列进行分组
mysql> select student_id, course_id, score from score group by student_id, course_id, score;
+------------+-----------+-------+
| student_id | course_id | score |
+------------+-----------+-------+
| 1 | 1 | 70.5 |
| 1 | 3 | 98.5 |
| 1 | 5 | 33 |
| 1 | 6 | 98 |
| 2 | 1 | 60 |
| 2 | 5 | 59.5 |
| 3 | 1 | 33 |
| 3 | 3 | 68 |
| 3 | 5 | 99 |
| 4 | 1 | 67 |
| 4 | 3 | 23 |
| 4 | 5 | 56 |
| 4 | 6 | 72 |
| 5 | 1 | 81 |
| 5 | 5 | 37 |
| 6 | 2 | 56 |
| 6 | 4 | 43 |
| 6 | 6 | 79 |
| 7 | 2 | 80 |
| 7 | 6 | 92 |
+------------+-----------+-------+
20 rows in set (0.00 sec)
- 统计以下每个分组的记录数
mysql> select student_id, course_id, score, count(*) from score group by student_id, course_id, score;
+------------+-----------+-------+----------+
| student_id | course_id | score | count(*) |
+------------+-----------+-------+----------+
| 1 | 1 | 70.5 | 2 |
| 1 | 3 | 98.5 | 2 |
| 1 | 5 | 33 | 1 |
| 1 | 6 | 98 | 1 |
| 2 | 1 | 60 | 2 |
| 2 | 5 | 59.5 | 1 |
| 3 | 1 | 33 | 1 |
| 3 | 3 | 68 | 1 |
| 3 | 5 | 99 | 1 |
| 4 | 1 | 67 | 1 |
| 4 | 3 | 23 | 1 |
| 4 | 5 | 56 | 1 |
| 4 | 6 | 72 | 1 |
| 5 | 1 | 81 | 1 |
| 5 | 5 | 37 | 1 |
| 6 | 2 | 56 | 1 |
| 6 | 4 | 43 | 1 |
| 6 | 6 | 79 | 1 |
| 7 | 2 | 80 | 1 |
| 7 | 6 | 92 | 1 |
+------------+-----------+-------+----------+
20 rows in set (0.00 sec)
- 如果分组的记录大于1,则表示有重复记录,对分组的结果进行过滤
mysql> select student_id, course_id, score, count(*) from score group by student_id, course_id, score having count(*) > 1;
+------------+-----------+-------+----------+
| student_id | course_id | score | count(*) |
+------------+-----------+-------+----------+
| 1 | 1 | 70.5 | 2 |
| 1 | 3 | 98.5 | 2 |
| 2 | 1 | 60 | 2 |
+------------+-----------+-------+----------+
3 rows in set (0.00 sec)
- 确定内层的条件
mysql> select student_id, course_id, score from score group by student_id, course_id, score having count(*) > 1;
+------------+-----------+-------+
| student_id | course_id | score |
+------------+-----------+-------+
| 1 | 1 | 70.5 |
| 1 | 3 | 98.5 |
| 2 | 1 | 60 |
+------------+-----------+-------+
3 rows in set (0.00 sec)
- 加入外层查询
mysql> select * from score where (student_id, course_id, score) in (select student_id, course_id, score from score group by student_id, course_id, score having count(*) > 1);
+----+------------+-----------+-------+
| id | student_id | course_id | score |
+----+------------+-----------+-------+
| 1 | 1 | 1 | 70.5 |
| 2 | 1 | 3 | 98.5 |
| 5 | 2 | 1 | 60 |
| 21 | 1 | 1 | 70.5 |
| 22 | 1 | 3 | 98.5 |
| 23 | 2 | 1 | 60 |
+----+------------+-----------+-------+
6 rows in set (0.00 sec)
内层查询结果中的列与外层条件中的列一定要匹配。
5.5 在from 子句中使用子查询
当一个查询产生结果时,MySQL自动创建一个临时表,然后把结果集放在这个临时表中,最终返回给用户,在from子句中也可以使用临时表进行子查询或表连接操作。
- 查询所有比“Java001班”平均分高的成绩信息
- 先算出Java001班的平均分
select * from score sco, (
-- 1. 使用子查询返回的值,用于where子句中
-- 2. 使用子查询生成的临时表,用于form子句中
select avg(sco.score) as avg_score from score sco, student stu, class c
where
stu.id = sco.student_id
and
stu.class_id = c.id
and
c.name = 'Java001班') as temp -- 为临时表起一个别名,以便在条件过滤中使用临时表
where sco.score > temp.avg_score;+----+------------+-----------+-------+-----------+
| id | student_id | course_id | score | avg_score |
+----+------------+-----------+-------+-----------+
| 1 | 1 | 1 | 70.5 | 66.65625 |
| 2 | 1 | 3 | 98.5 | 66.65625 |
| 4 | 1 | 6 | 98 | 66.65625 |
| 8 | 3 | 3 | 68 | 66.65625 |
| 9 | 3 | 5 | 99 | 66.65625 |
| 10 | 4 | 1 | 67 | 66.65625 |
| 13 | 4 | 6 | 72 | 66.65625 |
| 14 | 5 | 1 | 81 | 66.65625 |
| 18 | 6 | 6 | 79 | 66.65625 |
| 19 | 7 | 2 | 80 | 66.65625 |
| 20 | 7 | 6 | 92 | 66.65625 |
| 21 | 1 | 1 | 70.5 | 66.65625 |
| 22 | 1 | 3 | 98.5 | 66.65625 |
+----+------------+-----------+-------+-----------+
13 rows in set (0.00 sec)
6. 合并查询
在实际应用中,为了合并多个select操作返回的结果,可以使用集合操作符union,union all
-- 创建student1表
mysql> create table student1 like student;
Query OK, 0 rows affected (0.06 sec)
-- 插入数据
mysql> 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: 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 |
+----+--------+--------+------+--------+-------------+----------+
4 rows in set (0.01 sec)
6.1 Union
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。
- ** 查询student表中id<3 的同学 和 student1 表中的所有同学**
mysql> select * from student where id < 3;
+----+--------+--------+------+--------+-------------+----------+
| 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 rows in set (0.00 sec)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)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.2 Union all
该操作符用于取两个结果集中的并集。当使用该操作符时,不会去掉结果中的重复行。
- 查询student表中id<3 的同学 和 student1 表中的所有同学
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_id-> from 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.01 sec)
为重复的列指定 表名.列号 , 不重复的列可以不用加表名,但是还是推荐使用表名.列名 的方式指定查询列表。