目录

MySQL表的设计

查询进阶版本

插入查询结果-->属于新增

聚合查询

group by子句

having子句

联合查询

外连接

对比外连接和内连接:

自连接

子查询

合并查询


MySQL表的设计

我们一般将表的设计分为3种类型 一对一 , 一对多(或者是多对一),多对多.以下示例我以学生为例

  • 一对一

比如学生和账户 : 一个学生只能有一个账户(排除其他情况),一个账户只能包含一个学生.

这就是一种一对一的关系,我们如何设计表让其形成这样的关系呢??

mysql一对多查询查询多表数据组装 mysql一对一查询_一对一

学生和账户之间依靠 id来联系. 这就是一对一的关系.

我们可以 student(name accountId) account(accountId ,password)和student(name,studentId) account(studentId,password);  任意一种都可以,相关联的id可以使学生的学号也可以是账户的id;

设计表

mysql> create table student(id int primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.03 sec)

mysql> create table account(password int ,id int primary key auto_increment,foreign key(id) references student(id));
Query OK, 0 rows affected (0.03 sec)
  • 一对多

什么情况会出现一对多呢?? 比如一个学生只能有一个班级,一个班级对应着多个学生.

学生和班级 也就是有两个表 学生表和班级表 两个依靠class_id(班级ID) 相关联 

mysql一对多查询查询多表数据组装 mysql一对一查询_聚合函数_02

 设计表

mysql> create table class(class_id int primary key auto_increment,foreign key(class_id) references student(class_id));
Query OK, 0 rows affected (0.03 sec)

mysql> desc student;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| class_id | int(11)     | NO   | PRI | NULL    | auto_increment |
| name     | varchar(20) | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
create table class(name varchar(20), class_id int primary key auto_increment,foreign key(class_id) references student(class_id));
Query OK, 0 rows affected (0.03 sec)

mysql> desc class;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| name     | varchar(20) | YES  |     | NULL    |                |
| class_id | int(11)     | NO   | PRI | NULL    | auto_increment |
+----------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
  • 多对多

多对多的关系 比如 学生和课程之间的关系,一个学生可以有选择多门课程,一门课程可以包含多个学生. 多对多的关系我们需要借助学生和课程之间的一个表来联系,这个表保存着学生ID和课程ID

mysql一对多查询查询多表数据组装 mysql一对一查询_一对一_03

设计表

mysql> create table student(student_id int primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.02 sec)

mysql> create table course(course_id int primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.03 sec)

mysql> create table student_course(student_id int,course_id int, foreign key(student_id) references student(student_id),foreign key(course_id) references course(course_id));
Query OK, 0 rows affected (0.03 sec)

mysql> desc student;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| student_id | int(11)     | NO   | PRI | NULL    | auto_increment |
| name       | varchar(20) | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> desc course;
+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| course_id | int(11)     | NO   | PRI | NULL    | auto_increment |
| name      | varchar(20) | YES  |     | NULL    |                |
+-----------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> desc student_course;
+------------+---------+------+-----+---------+-------+
| Field      | Type    | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| student_id | int(11) | YES  | MUL | NULL    |       |
| course_id  | int(11) | YES  | MUL | NULL    |       |
+------------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)

查询进阶版本

插入查询结果-->属于新增

插入查询就是将查询结果插入到一个临时表中,其中要注意的是,查询结果的临时表要与插入的表列数和类型一致.

mysql> create table ID(name varchar(20),id int);
Query OK, 0 rows affected (0.03 sec)

mysql> insert into Id values('张三',90),('李四',23),('王五',45),('老李',11);
Query OK, 4 rows affected (0.01 sec)

mysql> insert into student(name,id) select * from ID;
Query OK, 4 rows affected (0.01 sec)
insert into student(name,id) select * from ID;

插入语法: insert into 表名(全列或者单列) select (全列或者单列) from 表名 [条件] ;

聚合查询

聚合函数

  • count

count->用来计算查询出数据的个数 ;

count(*) ->代表查询统计所有的数据,如果有NULL也计数,count(列)->代表统计这一列的数据个数,如果有NULL,不进行计数.

还要注意一点 如果count后面加上空格在加小括号 就会报错 SQL无法解析;

示例:

mysql> select * from student;
+----+---------+------+
| id | chinese | math |
+----+---------+------+
|  1 |    NULL |   58 |
|  2 |       0 | NULL |
|  3 |      56 |   89 |
|  4 |       2 |   65 |
+----+---------+------+
4 rows in set (0.00 sec)

mysql> select count(*) from student;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)
-- 计算单列时:
mysql> select count(chinese) from student;
+----------------+
| count(chinese) |
+----------------+
|              3 |
+----------------+
1 row in set (0.00 sec)
  • sum

sum函数时进行求和,求和NULL不计入. NULL与任何数计算都是NULL,同时在进行聚合查询时也可以根据筛选条件进行查询

select * from student;
+----+---------+------+
| id | chinese | math |
+----+---------+------+
|  1 |    NULL |   58 |
|  2 |       0 | NULL |
|  3 |      56 |   89 |
|  4 |       2 |   65 |
+----+---------+------+

mysql> select sum(chinese) from student;
+--------------+
| sum(chinese) |
+--------------+
|           58 |
+--------------+
-- 根据筛选math>60的总成绩

select sum(math) from student where math>60;
+-----------+
| sum(math) |
+-----------+
|       154 |
+-----------+
  • avg

avg用来计算平均数据

select * from student;
+----+---------+------+
| id | chinese | math |
+----+---------+------+
|  1 |    NULL |   58 |
|  2 |       0 | NULL |
|  3 |      56 |   89 |
|  4 |       2 |   65 |
+----+---------+------+

select avg(math) from student;
+-----------+
| avg(math) |
+-----------+
|   70.6667 |
+-----------+
  • max 和min

max和min 用来计算某一列的最大值和最小值

select * from student;
+----+---------+------+
| id | chinese | math |
+----+---------+------+
|  1 |    NULL |   58 |
|  2 |       0 | NULL |
|  3 |      56 |   89 |
|  4 |       2 |   65 |
+----+---------+------+
4 rows in set (0.00 sec)

mysql> select max(math),min(math),max(chinese),min(chinese) from student;
+-----------+-----------+--------------+--------------+
| max(math) | min(math) | max(chinese) | min(chinese) |
+-----------+-----------+--------------+--------------+
|        89 |        58 |           56 |            0 |
+-----------+-----------+--------------+--------------+

group by子句

group by 字句是依据列数来分组,列数相同的归为一组,查询时也可以使用聚合函数

语法 : select 要显示的列..可以使用聚合函数 from 表名 group by (列) <-根据这个列进行分组
select * from student;
+--------+--------+---------+------+---------+
| name   | gender | chinese | math | english |
+--------+--------+---------+------+---------+
| 张三   | 男     |      56 |   89 |      21 |
| 李四   | 女     |      32 |   60 |      37 |
| 王五   | 男     |      65 |   30 |       2 |
| 小美   | 女     |      10 |   90 |      38 |
+--------+--------+---------+------+---------+
4 rows in set (0.00 sec)

select gender, avg(math) as "数学平均成绩" ,max(chinese) as "语文最高分",sum(english) from student group by gender;
+--------+--------------------+-----------------+--------------+
| gender | 数学平均成绩       | 语文最高分      | sum(english) |
+--------+--------------------+-----------------+--------------+
| 女     |            75.0000 |              32 |           75 |
| 男     |            59.5000 |              65 |           23 |
+--------+--------------------+-----------------+--------------+

having子句

having子句是 group的一个固定搭配,having相当于条件子句的where,但是在聚合查询之后,如果还要进行条件过滤,那我们就需要使用having子句与group by进行搭配使用;

-- 在进行条件筛选时有三种情况

  • 聚合之前选择
mysql> -- 查询 除去张三同学 的性别的三科平均分数
mysql> select gender,avg(math+chinese+english) from student where name!="张三" group by gender;
+--------+---------------------------+
| gender | avg(math+chinese+english) |
+--------+---------------------------+
| 女     |                  133.5000 |
| 男     |                  155.0000 |
+--------+---------------------------+
  • 聚合之后选择
mysql> -- 查询 性别的平均成绩大于100的是男还是女

mysql> select * from student;
+--------+--------+---------+------+---------+
| name   | gender | chinese | math | english |
+--------+--------+---------+------+---------+
| 张三   | 男     |      56 |   89 |      21 |
| 李四   | 女     |      32 |   60 |      37 |
| 王五   | 男     |      65 |   30 |       2 |
| 小美   | 女     |      10 |   90 |      38 |
| 小明   | 男     |      85 |   96 |      32 |
+--------+--------+---------+------+---------+

mysql> select gender, avg(math+chinese+english) as "三科平均成绩" from student group by gender having avg(math+chinese+english)>=150.0;
+--------+--------------------+
| gender | 三科平均成绩       |
+--------+--------------------+
| 男     |           158.6667 |
+--------+--------------------+
  • 聚合之前之后都查询
mysql> select * from student;
+--------+--------+---------+------+---------+
| name   | gender | chinese | math | english |
+--------+--------+---------+------+---------+
| 张三   | 男     |      56 |   89 |      21 |
| 李四   | 女     |      32 |   60 |      37 |
| 王五   | 男     |      65 |   30 |       2 |
| 小美   | 女     |      10 |   90 |      38 |
| 小明   | 男     |      85 |   96 |      32 |
+--------+--------+---------+------+---------+

mysql> select gender, avg(math+chinese+english) from student where name != "张三" group by gender having avg(math+chinese+english)>=140;
+--------+---------------------------+
| gender | avg(math+chinese+english) |
+--------+---------------------------+
| 男     |                  155.0000 |
+--------+---------------------------+
  • 总结

在聚合查询时 先整清楚是聚合之前还是聚合之后还是聚合之前聚合之后都要查询.

  • 如果是聚合之前查询先用where进行筛选在通过group by进行分组,可以使用聚合函数来显示最终结果
  • 如果是聚合之后查询,先要进行group by子句来分组,在使用having字句来过滤条件,可以使用聚合函数来显示最终结果
  • 如果聚合之前之后都要查询,先使用where把聚合之前的条件进行筛选,再根据group by来进行分组,在使用having子句在聚合之后进行查询,可以使用聚合函数来显示最终结果.

联合查询

联合查询就是将多表结合在一起查询,将两个表排列组合成一个表进行一系列操作,这也叫做笛卡尔积.

联合查询步骤:

  1. 先根据条件进行确定哪个表使用
  2. 在对多个表进行笛卡尔积
  3. 确定连接条件,过滤掉重复数据
  4. 进一步增加条件,查询与需要的结果相符
  5. 去掉无关的列,显示最终的结果

笛卡尔积: 

将两表进行合并 : select (要查询的列) from 表名 , 表名

还可以这样合并 : select(要查询的列) from 表名 join 表名 (可以join多个表名)..... on ....(条件)

笛卡尔积的列数就是几个表的列数之和

笛卡尔积的行数就是几个表的行数乘积

这也叫做内连接 -> 两个表中的列的交集 ->包含这两张表的数据

drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;

create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));

create table student (id int primary key auto_increment, sn varchar(20),  name varchar(20), qq_mail varchar(20) ,
        classes_id int);

create table course(id int primary key auto_increment, name varchar(20));

create table score(score decimal(3, 1), student_id int, course_id int);

insert into classes(name, `desc`) values 
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班','学习了中国传统文学'),
('自动化2019级5班','学习了机械自动化');

insert into student(sn, name, qq_mail, classes_id) values
('09982','黑旋风李逵','xuanfeng@qq.com',1),
('00835','菩提老祖',null,1),
('00391','白素贞',null,1),
('00031','许仙','xuxian@qq.com',1),
('00054','不想毕业',null,1),
('51234','好好说话','say@qq.com',2),
('83223','tellme',null,2),
('09527','老外学中文','foreigner@qq.com',2);

insert into course(name) values
('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');

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),
-- tellme
(80, 7, 2),(92, 7, 6);
  • 查询“许仙”同学的 成绩

1.先进行笛卡尔积

mysql> select * from student,score; -- 将两个表合并-进行笛卡尔积

2.既然雅查询许仙的乘积,那么它的学生id是一致的,不一致的就不符合条件

mysql> select * from score,student where student.id = score.student_id;
-- 分数表的学生id和学生表的学生id是相同的

select student.name ,score.score from student join score on student.id = score.student_id and student.name = '许仙';
-- 也可以使用join ... on

3.继续筛选条件 名字为许仙的.

mysql> select * from score,student where student.id = score.student_id and student.name="许仙";

4.精简表格

mysql> select student.name ,score.score from student,score where student.id = score.student_id and student.name = '许仙';
+--------+-------+
| name   | score |
+--------+-------+
| 许仙   |  67.0 |
| 许仙   |  23.0 |
| 许仙   |  56.0 |
| 许仙   |  72.0 |
+--------+-------+
  • 查询所有同学的总成绩,及同学的个人信息

首先,要查询同学的总成绩-->成绩表   同学的个人信息 ->同学表,我们将这两个表进行合并,要保证一个同学在成绩表和同学表一一对应,所以两个表的id要相等,因为要求同学的总成绩,我们就要使用聚合查询,首先先根据id进行分组,利用聚合函数sum求得每个id的总成绩.

  1. 保证每个学生唯一 ,进行学生表和分数表笛卡尔积
-- 保证每个学生一一对应 学生表的id和分数表的id是相同的
mysql> select * from student,score where student.id = score.student_id;

2.根据id进行分组

mysql> select student.name,sum(score) from student,score where student.id = score.student_id group by id;
+-----------------+------------+
| name            | sum(score) |
+-----------------+------------+
| 黑旋风李逵      |      300.0 |
| 菩提老祖        |      119.5 |
| 白素贞          |      200.0 |
| 许仙            |      218.0 |
| 不想毕业        |      118.0 |
| 好好说话        |      178.0 |
| tellme          |      172.0 |
+-----------------+------------+

3.使用聚合函数求得每个人的总成绩

mysql> select student.name,student.id,student.qq_mail,student.classes_id,sum(score) as "总成绩" from student,score where student.id = score.student_id group by id;
+-----------------+----+-----------------+------------+-----------+
| name            | id | qq_mail         | classes_id | 总成绩    |
+-----------------+----+-----------------+------------+-----------+
| 黑旋风李逵      |  1 | xuanfeng@qq.com |          1 |     300.0 |
| 菩提老祖        |  2 | NULL            |          1 |     119.5 |
| 白素贞          |  3 | NULL            |          1 |     200.0 |
| 许仙            |  4 | xuxian@qq.com   |          1 |     218.0 |
| 不想毕业        |  5 | NULL            |          1 |     118.0 |
| 好好说话        |  6 | say@qq.com      |          2 |     178.0 |
| tellme          |  7 | NULL            |          2 |     172.0 |
+-----------------+----+-----------------+------------+-----------+
  • 查询所有同学的成绩,及同学的个人信息

这个题的意思是查询这个同学的所有课程成绩及信息.

那我们就需要准备同学->学生表,成绩->分数表,课程->课程表

将这三个表进行笛卡尔积

select * from student join score join course ;
-- 将这三个表进行笛卡尔积

可以知道一个学生在学生表的id和分数表的id就能确定某个学生的分数,学生表的分数的课程id和课程表的id就能确定这个学生选修的课程

mysql> select student.id,student.name,course.name,score.score from student join score join course where student.id = score.student_id and course.id = score.course_id;
+----+-----------------+--------------------+-------+
| id | name            | name               | score |
+----+-----------------+--------------------+-------+
|  1 | 黑旋风李逵      | Java               |  70.5 |
|  1 | 黑旋风李逵      | 计算机原理          |  98.5 |
|  1 | 黑旋风李逵      | 高阶数学            |  33.0 |
|  1 | 黑旋风李逵      | 英文               |  98.0 |
|  2 | 菩提老祖        | Java               |  60.0 |
|  2 | 菩提老祖        | 高阶数学           |  59.5 |
|  3 | 白素贞          | Java               |  33.0 |
|  3 | 白素贞          | 计算机原理         |  68.0 |
|  3 | 白素贞          | 高阶数学           |  99.0 |
|  4 | 许仙            | Java               |  67.0 |
|  4 | 许仙            | 计算机原理         |  23.0 |
|  4 | 许仙            | 高阶数学           |  56.0 |
|  4 | 许仙            | 英文               |  72.0 |
|  5 | 不想毕业        | Java               |  81.0 |
|  5 | 不想毕业        | 高阶数学           |  37.0 |
|  6 | 好好说话        | 中国传统文化       |  56.0 |
|  6 | 好好说话        | 语文               |  43.0 |
|  6 | 好好说话        | 英文               |  79.0 |
|  7 | tellme          | 中国传统文化       |  80.0 |
|  7 | tellme          | 英文               |  92.0 |
+----+-----------------+--------------------+-------+
20 rows in set (0.00 sec)

外连接

外连接与内连接相对应,内连接是将两个表的共有数据全部显示出来,而外连接是只显示一部分,即左半部分和右半部分.

语法:
 -- 左外连接 ->保证join左边的表完整,如果右侧不完整则为NULL
 select 列名 from  表名 left   join 表名 on 条件  
 -- 右外连接 ->保证join右边的表完整,如果左侧不完整则为NULL 
 select 列名 from  表名 right  join 表名 on 条件

创建的两张表:

mysql> select * from score;
+------+-------+
| id   | score |
+------+-------+
|    1 |    98 |
|    2 |    76 |
|    4 |    12 |
+------+-------+
3 rows in set (0.02 sec)

mysql> select * from student;
+------+--------+
| id   | name   |
+------+--------+
|    1 | 张三   |
|    2 | 李四   |
|    3 | 王五   |
+------+--------+

左外连接:

mysql> select name,score from score left join student on student.id = score.id;
+--------+-------+
| name   | score |
+--------+-------+
| 张三   |    98 |
| 李四   |    76 |
| NULL   |    12 |
+--------+-------+
3 rows in set (0.00 sec)

右外连接:

mysql> select name,score from score right join student on student.id = score.id;
+--------+-------+
| name   | score |
+--------+-------+
| 张三   |    98 |
| 李四   |    76 |
| 王五   |  NULL |
+--------+-------+
3 rows in set (0.00 sec)

对比外连接和内连接:

mysql一对多查询查询多表数据组装 mysql一对一查询_一对一_04

 内连接只显式两张表共有的数据.

而外连接时都要显式,左外连接是保证左侧数据齐全准确,而右侧数据如果没有则显式NULL,右外连接是保证右侧数据齐全准确,而左侧数据如果没有则显式NULL

自连接

自连接,顾名思义就是自己连接自己,将两张一样的表进行笛卡尔积.

  • 显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

mysql一对多查询查询多表数据组装 mysql一对一查询_数据库_05

 根据查询我们知道课程表中计算机原理是课程id 3号,而java是课程id1号,所以就转化为求课程id3号的同学大于课程id1号的同学; 

由于在分数表中课程id比较是要根据行和行进行比较,由于我们只能列和列之间进行比较,所以我们需要将两个一样的分数表进行笛卡尔积->也叫作自连接.

同样的保证学生不重复,要保证学生的信息一直,所以学生的id是相同的 ->这里要注意自连接时不能score join score ,自连接时必须要使用别名.

mysql> select * from score as s1 join score as s2 on s1.student_id = s2.student_id;

由于我们要比较3号课程和1号课程,所以我们要确保课程是3号和1号课程

mysql> select * from score as s1 join score as s2 on s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id = 1;
+-------+------------+-----------+-------+------------+-----------+
| score | student_id | course_id | score | student_id | course_id |
+-------+------------+-----------+-------+------------+-----------+
|  98.5 |          1 |         3 |  70.5 |          1 |         1 |
|  68.0 |          3 |         3 |  33.0 |          3 |         1 |
|  23.0 |          4 |         3 |  67.0 |          4 |         1 |
+-------+------------+-----------+-------+------------+-----------+

接下来在保证结果为3号课程的分数大于1号课程的分数

mysql> select * from score as s1 join score as s2 on s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id = 1 and s1.score > s2.score;
+-------+------------+-----------+-------+------------+-----------+
| score | student_id | course_id | score | student_id | course_id |
+-------+------------+-----------+-------+------------+-----------+
|  98.5 |          1 |         3 |  70.5 |          1 |         1 |
|  68.0 |          3 |         3 |  33.0 |          3 |         1 |
+-------+------------+-----------+-------+------------+-----------+
2 rows in set (0.00 sec)
  • 自连接要注意的点:

在进行笛卡尔积的时候必须使用别名

子查询

这里的子查询就是套娃,也就是分步骤执行,将两个查询,通过查询某个重要的信息,再根据这个信息再次查询就得到最终结果.

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询
 

  • 查询与“不想毕业” 同学的同班同学

第一步我们要先查询不想毕业同学的课程id

mysql> select student.classes_id from student where name = "不想毕业";
+------------+
| classes_id |
+------------+
|          1 |
+------------+

第二步查询classes_id和不想毕业同学一样的同学的名字,但是这里的名字不包括不想毕业,因为不想毕业的同班同学不能有它自己.

mysql> select student.name from student where student.classes_id=1 and name!="不想毕业";
+-----------------+
| name            |
+-----------------+
| 黑旋风李逵      |
| 菩提老祖        |
| 白素贞          |
| 许仙            |
+-----------------+

我们可以将上面两个步骤合并成一个如下:

mysql> select name from student where student.classes_id = (select student.classes_id from student where student.name = "不想毕业") and student.name != "不想毕业";
+-----------------+
| name            |
+-----------------+
| 黑旋风李逵      |
| 菩提老祖        |
| 白素贞          |
| 许仙            |
+-----------------+
  • 查询“语文”或“英文”课程的成绩信息

先根据语文和英文在对应的课程表中找到课程id

mysql> select course.id from course where course.name = "语文" or course.name = "英文";
+----+
| id |
+----+
|  4 |
|  6 |
+----+

再根据课程id去分数表中找到对应的信息

mysql> select * from score where score.course_id = 4 or score.course_id = 6;
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  98.0 |          1 |         6 |
|  72.0 |          4 |         6 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+

-- 这里也可以使用 in
mysql> select * from score where score.course_id in(4,6);
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  98.0 |          1 |         6 |
|  72.0 |          4 |         6 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+

将这两个步骤进行合并操作

select * from score where score.course_id in(select course.id from course where course.name in ("英文","语文"));
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  98.0 |          1 |         6 |
|  72.0 |          4 |         6 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+

合并查询

就是将两个查询合并成一个

比如我要查询id小于3,或者名字为“英文”的课程

mysql> select * from course where course.id<3 or course.name = "英文";
+----+--------------------+
| id | name               |
+----+--------------------+
|  1 | Java               |
|  2 | 中国传统文化       |
|  6 | 英文               |
+----+--------------------+

我们可以查询id<3的,在查询name = 英文的,然后将两个查询进行合并

mysql> select * from course where course.id < 3 union select * from course where course.name = "英文";
+----+--------------------+
| id | name               |
+----+--------------------+
|  1 | Java               |
|  2 | 中国传统文化       |
|  6 | 英文               |
+----+--------------------+
3 rows in set (0.00 sec)
  • union 该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行
     
  • union all 该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行
     
mysql> select id from course where course.name = "英文" union all select id from course where course.name = "英文";
+----+
| id |
+----+
|  6 |
|  6 |
+----+
2 rows in set (0.00 sec)

mysql> select id from course where course.name = "英文" union select id from course where course.name = "英文";
+----+
| id |
+----+
|  6 |
+----+
1 row in set (0.00 sec)