子查询
将结果来作为另一个查询的参数
创建和使用返回单值的子查询
在多表查询中使用子查询
在student表查询“计算机入门”课程的学生学号、姓名和成绩,使用连接表的方法,如下:
select sno,sname,mark
from student as s
inner join course as c
on s.cno=c.cno where cname="计算机入门";
采用子查询的方式,如下:
select sno,sname,mark
from student
where cno=(select cno from course where cname="计算机入门");
在子查询中使用聚合函数
1)在teacher表查询年龄高于平均年龄的教师工号、姓名、专业和年龄信息
select tno,tname,dname,age
from teacher
where age>(select avg(age) from teacher)
order by age;
2)在teacher中查询教师的信息,并且要求教师所在专业的平均年龄大于所有教师的平均年龄
select tno,tname,dname,cno,age
from teacher as t
where
(select avg(age) from teacher where dname=t.dname) > (select avg(age) from teacher);
创建和使用返回多行的子查询
in子查询
in运算符用于集合成员的测试。
语法:
select colum_name
from table_name
where test expression [not] in (subquery)
这里,test expression可以是实际值、列名、表达式或另一个返回单一值的子查询。
例如查询存在不及格课程的学生的姓名、专业、所有课程和成绩信息:
select sname,dname,cno,mark
from student
where sno in (select sno from student where mark<60)
order by sname;
in子查询实现集合交和集合差运算
交运算
在student表中查询修过1号和10号课程的学生的信息,即修过1号课程的学生和修过10号课程的学生信息的交集。
select sno,sname,dname
from student
where cno=1 and sno in (select sno from student where cno=10);
差运算
在student表中查询修过1号但没有修过10号课程的学生的信息,即修过1号课程的学生和修过10号课程的学生信息的差集。
select sno,sname,dname
from student
where cno=1 and sno not in (select sno from student where cno=10);
exists子查询
某些情况下,我们只需要子查询返回一个True或者False,子查询数据内容本身并不重要,这时可以使用exists来定义子查询。exsits用来测试集合是否为空,它总是与子查询结合使用,而且只要子查询中至少返回一个值,exists判式就为true。
例如:在teacher表查询教师的信息,要求查询到的教师必须是其课程在student表中有学生修过的教师信息。
select tno,tname,dname,cno
from teacher as t
where exists(select * from student where cno=t.cno);
下面分析上面sql的执行过程:
执行查询时,系统一次处理teacher表的一行数据。当主查询中传送的是正在处理的当前行的课程号cno列值时,子查询就在student表查询该课程号的对应学生的信息,生成一个中间表。如果exists判式为false,where子句的结果就为false,那么系统转而处理teacher表的下一行。如果exists判式为true,系统将这一行记录的相关信息添加到主查询的结果表,而后继续处理下一行数据。
exists子查询实现两表交集
比如:在teacher表中查询女教师开设的、6月份考试的课程号、开课教师以及教师所在的专业。
select cno,tname,dname
from teacher
where tsex='女' and exists(select * from course where month(ctest)=7 and cno=teacher.cno)
order by cno;
some/all子查询
some、any和all允许使用比较运算符将单值与子查询返回的值加以比较。
表达式 | 含义 |
>some | 大于子查询结果中的某个值 |
>all | 大于子查询结果中的所值 |
<some | 小于子查询结果中的某个值 |
<all | 小于子查询结果中的所值 |
>=some | 大于等于子查询结果中的某个值 |
>=all | 大于等于子查询结果中的所值 |
<=some | 小于等于子查询结果中的某个值 |
<=all | 小于等于子查询结果中的所值 |
=some | 等于子查询结果中的某个值 |
=all | 大于子查询结果中的所值 |
!=some | 不等于子查询结果中的某个值 |
!=all | 不等于查询结果中的所值 |
比如:在student表中查询平均成绩最高的学生的学号以及平均成绩信息。
select sno,avg(mark) as avg_score
from student
group by sno
having avg(mark) >= all(select avg(mark) from student group by sno);
执行过程如下:
1)先根据学号将student表分组,得到中间表
2)执行having子句,从分组后的中间表取出一组,执行avg(mark)聚合函数得到平均成绩
3)执行子查询,返回student表中每个学生的平均成绩
4)判断>=all是否成立,如果成立,将该组的学号和平均成绩添加到主查询的结果表,接着处理下一组数据