今天来学习MySQL中的子查询
。子查询
就是指在一个查询之中嵌套了其余的若干查询,即在一个select
查询语句的where
和from
子句中包含另外一个select
查询语句,外层select
查询语句称为外层查询
或父查询
,where
子句中的select
语句称为内层查询
或子查询
。有时把上面这种状况也称为嵌套查询
。用户可使用多个简单的查询构成复杂的查询。本篇文章使用的数据和上一篇文章(MySQL学习笔记之对单表数据记录的查询操做)是同样的。sql
最简单的子查询是返回一个值,一般和比较运算符连用。如查询与“刘晨”在同一个系学习的学生:bash
# 查询与刘晨在同一个系学习的学生
select s_id, s_name, s_dept
from tab_student
where s_dept = (
select s_dept
from tab_student
where s_name = '刘晨'
);
复制代码
不相关子查询
,若是子查询的查询条件依赖于父查询,就被称为
相关子查询
。
通常当子查询返回的数据记录为多条时,通常会和IN、ANY、ALL和EXISTS
等关键字组合使用。函数
in
关键字主要用于查找属性值是否属于指定的集合,在《MySQL学习笔记之对单表数据记录的查询操做》文章中 已经学习了。由于子查询的结果每每是一个集合,因此in
关键字是常常使用的。post
# 查询选修了 2 号课程学生的姓名
select s_name
from tab_student
where s_id in (
select s_id
from tab_sc
where c_id = 2
);
复制代码
关键字any
用来表示父查询的条件为知足子查询返回结果中任意一条数据。能够和比较运算符进行组合:学习
经过样例进行理解:查询非计算机系中比计算机系任意一个学生年龄小的学生姓名和年龄,也能够理解成查询非计算机系中年龄比计算机系中最大年龄小的学生的姓名和年龄。ui
# 查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄
select s_name, s_age
from tab_student
where s_age < any (
select s_age
from tab_student
where s_dept = 'CS'
) and s_dept != 'CS';
复制代码
关键字all
和关键字any
在用法上比较类似,表示主查询的条件为知足子查询返回结果中全部数据记录。一样也能够和比较运算符组合使用:spa
经过样例进行理解:查询非计算机科学系中比计算机科学系全部学生年龄都小的学生姓名和年龄,也能够理解成非计算机系中学生的年龄比计算机系中最小年龄小的学生的姓名和年龄。code
# 查询非计算机科学系中比计算机科学系全部学生年龄都小的学生姓名和年龄
select s_name, s_age
from tab_student
where s_age < all(
select s_age
from tab_student
where s_dept = 'CS'
) and s_dept != 'CS';
复制代码
= | != | < | <= | > | >= | |
---|---|---|---|---|---|---|
any | in | -- | <max | <=max | >min | >=min |
all | -- | not in | <min | <=min | >max | >=max |
经过上表咱们知道同一个查询请求能够有多种方法,不一样的方法其执行效率是不同的,咱们应根据本身的实际状况进行选择。用统计函数实现子查询一般比直接用all
或any
查询效率高。注: =all
通常为永假,!=any
通常为永真。cdn
关键字exists
用来判断子查询是否返回结果集,有结果集时为true
不然为fasle
。如:查询全部选修了 3 号课程的学生姓名对象
# 查询全部选修了 3 号课程的学生姓名
select s_name
from tab_student
where exists (
select *
from tab_sc
where s_id = tab_student.s_id and c_id = 3
);
复制代码
tab_student.s_id
的值,与父查询有关,也就是咱们上面刚说的
相关子查询
。 与
exists
关键字对应的是
not exists
关键字,表示若是子查询结果为空,则外层的
where
子句返回真值,不然返回假值。
放在from
子句里面的子查询,会被看成一张临时表成为父查询的查询对象,必须为临时表指定一个别名。如:找出每一个学生超过他本身选修课程平均成绩的课程号。
# 找出每一个学生超过他本身选修课程平均成绩的课程号
select s_id, c_id
from tab_sc sc, (select s_id avg_id, avg(sc_grade) avg_grade
from tab_sc group by s_id
) as avg_sc
where sc.s_id = avg_sc.avg_id and sc.sc_grade >= avg_sc.avg_grade;
复制代码
今天学习了MySQL中关于子查询的一些基础操做。介绍了简单的子查询,学习了in, any, all, exists
关键字的使用和临时表基础操做等。今天的学习告一段落,本文中有不对或不许确的地方,欢迎在评论区指定出来。