子查询

将结果来作为另一个查询的参数

创建和使用返回单值的子查询

在多表查询中使用子查询

在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是否成立,如果成立,将该组的学号和平均成绩添加到主查询的结果表,接着处理下一组数据

 

 

posted @ 2017-04-29 16:07  且听风吟-wuchao  阅读(412)  评论(0编辑  收藏  举报