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

【MySQL】-- 联合查询

文章目录

  • 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)
  1. 参与查询的所有表取笛卡尔积(全排列),结果集存放在临时表中。
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)
  1. 观察哪些记录是有效数据,根据两个表的关联关系过滤掉无效数据。
-- 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)

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

  1. 通过指定列查询,精简查询结果
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)
  1. 通过给表起别名的方式来精简查询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 字段 from1 别名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 字段 from1 别名1 [inner] join2 别名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)
  1. 取两张表的笛卡尔积
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)
  1. 根据表与表之间的关系,确定过滤条件
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)
  1. 精简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)
  1. 取笛卡尔积(这里共有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)
  1. 查看表结构,确认表连接的条件
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)
  1. 添加过滤条件
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)
  1. 精简查询字段,得到最终结果
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不支持全外连接。

  1. 左外连接:返回左表的所有记录和右表中匹配的记录。如果右表中没有匹配的记录,则结果集中对应的字段会显示null。
  2. 右外连接:与左外连接相反,返回右表的所有记录和左表中匹配的记录。如果左表中没有匹配的记录,则结果集中对应字段会显示为null。
  3. 全外连接:结合了左外连接和右外连接的特点,返回左右表中的所有记录。如果某一边表中没有匹配的记录,则结果集中对应字段会显示为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)
  1. 对重复的列进行分组
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)
  1. 统计以下每个分组的记录数
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. 如果分组的记录大于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)
  1. 确定内层的条件
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)
  1. 加入外层查询
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班”平均分高的成绩信息
  1. 先算出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)

为重复的列指定 表名.列号 , 不重复的列可以不用加表名,但是还是推荐使用表名.列名 的方式指定查询列表。

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

相关文章:

  • Linux:进程控制1
  • 如何利用 QuickAPI 生成 PostgreSQL 样本测试数据:全面解析与实用指南
  • vue-qr生成的二维码增加下载功能
  • 【云备份】客户端开发
  • 百胜企业管理咨询:助力企业快速获得ecovadis认证
  • SecureCRT SFTP命令详解与实战
  • S32K3 HSE模块安装
  • 屏蔽力 | 在复杂世界中从内耗到成长的转变之道
  • STM32开发printf函数支持
  • LeetCode:二叉树的最大深度
  • React Native主题切换、字号调整:不用styled-components也能玩出花
  • 查询nvidia边缘设备的软硬件版本jetson_release
  • 【软件设计师:程序语言】4.程序语言基础知识
  • Unity-Socket通信实例详解
  • 【面试 · 二】JS个别重点整理
  • leetcode hot100 技巧
  • C++函数栈帧详解
  • Ultralytics中的YOLODataset和BaseDataset
  • comfyui 实现中文提示词翻译英文进行图像生成
  • 低成本监控IPC模组概述
  • D盘出现不知名文件
  • int (*)[3]和int (*arr_ptr)[3]区别
  • Spark应用部署模式实例
  • 个人网站versionI正式上线了!Personal Website for Jing Liu
  • ✍️【TS类型体操进阶】挑战类型极限,成为类型魔法师!♂️✨
  • JAVA八股文
  • CI/CD与DevOps流程流程简述(提供思路)
  • 使用pdm管理python项目时去哪里找nuitka
  • 如何通过复盘提升团队能力?
  • 数组和集合