一、含义
出现在其他语句中的 select 语句,称为子查询或内查询。外部的查询语句,称为主查询或外查询。
二、分类
1、按子查询出现的位置分类:
① select 后面
② from 后面
③ where 和 having 后面
2、按结果集的行列数分类:
①标量子查询(结果集只有一行一列)
②列子查询(结果集只有一列多行)
③行子查询(结果集有一行多列)
④表子查询(结果集一般为多行多列)
三、例子
1、数据
1)student 表
表结构
名 | 类型 | 长度 | 键 |
---|---|---|---|
id | int | 11 | 主键 |
name | varchar | 255 | 无 |
age | int | 11 | 无 |
class | varchar | 255 | 无 |
deskmate_id | int | 11 | 无 |
数据表
id | name | age | class | deskmate_id |
---|---|---|---|---|
1 | 小张 | 10 | 一班 | 4 |
2 | 小王 | 12 | 二班 | 3 |
3 | 小姣 | 18 | 二班 | 2 |
4 | 小兴 | 15 | 一班 | 1 |
2)curriculum 表
表结构
名 | 类型 | 长度 | 键 |
---|---|---|---|
id | int | 11 | 主键 |
student_id | int | 11 | 无 |
curriculum_name | varchar | 255 | 无 |
数据表
id | name | student_id |
---|---|---|
1 | 1 | C |
2 | 2 | C |
3 | 5 | C# |
4 | 3 | Python |
5 | 1 | Java |
2、操作符
当返回多行时,使用多行比较操作符。IN 是 = ANY 的别名,二者相同,但 NOT IN 的别名却不是 <> ANY 而是 <> SOME。NOT IN 是 <> ALL 的别名,二者相同。
操作符 | 含义 |
---|---|
in / not in | 属于/不属于子查询结果的值 |
any|some | ANY 关键字必须接在一个比较操作符的后面,表示与子查询返回的任何值比较为 TRUE ,则返回 TRUE |
all | 与比较操作符结合使用,和子查询结果的所有值比较 |
3、标量子查询
查询谁的年龄比小王大。
select name
from student
where age>(
select age
from student
where name='小王'
);
运行结果:
name |
---|
小姣 |
小兴 |
4、列子查询
查找课程名为"C"的所有学生。
select name
from student
where id in(
select student_id
from curriculum
where curriculum_name='C'
);
运行结果:
name |
---|
小张 |
小王 |
5、行子查询
行子查询是指子查询返回的结果集是一行 n 列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。
where 后面的 (1,2) 被称为行构造符,也可以写作 row(1,2),行构造符通常用于与对能返回两个或两个以上列的子查询进行比较。该语句的意思是当 student_id 为 1,curriculum_name 为'c'时,返回 student 表中的所有数据。
select *
from student
where (1,'c') =(
select min(student_id),min(curriculum_name)
from curriculum
);
6、表子查询
该语句的意思是当 student_id 为 1,curriculum_name 为'c'属于 curriculum 表时,返回 student 表中的所有数据。
select *
from student
where (1,'c') in(
select student_id,curriculum_name
from curriculum
);
7、select 后面仅仅支持标量子查询
查找所有学生的课程个数。
select *,(
select count(*)
from curriculum b
where a.id=b.student_id
) 个数
from student a;
运行结果
name | 个数 |
---|---|
小张 | 2 |
小王 | 1 |
小姣 | 1 |
小兴 | 0 |
8、from 后面将子查询结果充当一张表,要求必须起别名
将 curriculum 表中课程名称为'C'的数据和 student 表进行连接。
select a.name,a.class,b.curriculum_name
from student a inner join (
select *
from curriculum
where curriculum_name='c'
) b on a.id=b.student_id;
name | class | curriculum_name |
---|---|---|
小张 | 一班 | C |
小王 | 二班 | C |
9、exists 后面(相关子查询)
exists 用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值 true 或 false。exists 指定一个子查询,检测行是否的存在。
如果 curriculum 表存在名字为'C'的课程,则输出 student 表的所有数据。
select *
from student
where exists (
select *
from curriculum
where curriculum_name='C');
10、特点
①子查询放在小括号内。
②子查询一般放在条件的右侧。
③标量子查询,一般搭配着单行操作符使用>、<、>= 等等。
④列子查询,一般搭配着多行操作符使用 in、any/some、all。
⑤子查询的执行优先于主查询的执行。
标题:MySQL中的子查询
作者:Yi-Xing
地址:http://47.94.239.232/articles/2019/10/09/1570623943771.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!