子查询是嵌套在另一个查询的where子句中的select-from-where表达式。通常用于对集合的成员资格、集合的比较以及集合的基数进行检查。
in
:测试元组是否是集合中的成员not in
:测试元组是否不是集合中的成员单属性关系中测试成员资格
select distinct course_id
from section
where semester = 'Fall' and year = 2009 and
course_id in (select distinct course_id
from section
where semester = 'Spring' and year = 2010);
in
和 not in
也能作用于枚举集合
select distinct name
from instructor
where name not in ('Mozart','Einsten');
测试任意关系的成员资格
select count(distinct ID)
from takes
where(course_id,sec_id,semester,year)in(select course_id,sec_id,semester,year
from teaches
where teaches.ID = 10101);
> some
:至少比某一个要大(any
和some
的用法大致相同)找出满足下面条件的所有教师的姓名,他们的工资至少比Biology系某一个教师的工资要高
select name
from instructor
where salary >some (select salary
from instructor
where dept_name = 'Biology');
,<=some
,>=some
,=some
,<>some
的比较,=some
等价于in
,然而<>some
并不等价于not in
>all
比所有都大,<=all
,>=all
,=all
,<>all
的比较,<>all
等价于not in
,然而=all
并不等价于in
exists
:测试子查询结果中是否存在元组,在作为参数的子查询非空时返回true值not exists
:测试子查询结果中是否不存在元组,在作为参数的子查询为空时返回true值子查询通常都用“*”,existis的子查询只返回真值或假值,给出列名并无实际意义
找出在2009年秋季学期和2010年春季学期同时开课的 所有课程
select sname
from s
where exists
(select *
from sc
where sc.sno=s.sno and cno= ‘001’);
来自外层查询的相关名称(上述例子中S)可以用在where
子句中
找出选修了Biology系开设的所有课程的学生
可以将“关系A包含关系B”写成“not exists (B except A)
”
对每个学生测试其选修的所有课程集合是否包含Biology系开设的所有课程
select S.ID,S.name
from student as S
where not exists((select course_id
from course
where dept_name = 'Biology')
except
select T.course_id
from takes as T
where S.ID = T.ID);
unique
:测试子查询结果是否存在重复元组,如果没有出现重复元组,返回truenot unique
:测试子查询结果是否存在重复元组,如果出现重复元组,返回true找出所有在2009年最多开设一次的课程
如果某课程在2009年开设大于一次,则会出现重复的course_id查询结果,unique
就会返回false
一个元组的多个副本中,只要有一个属性为空,unique就有可能为真,因为元组t1和t2某个域为空时,判断t1=t2为假
select T.course_id
from course as T
where unique(select R.course_id
from section as R
where T.course_id = R.course_id and R.year = 2009);
任何select-from-where表达式返回的结果都是关系,因而可以被插入到另一个select-from-where中任何关系可以出现的位置
原先 having
子句的查询
select dept_name,avg(salary)
from instructor
group by dept_name
having avg(salary) > 42000;
写成 from
子句的子查询后
可以用as子句给此子查询的结果关系起个名字,并对属性进行重命名
select dept_name,avg_salary
from (select dept_name,avg(salary) as avg_salary
from instructor
group by dept_name)
as dept_avg(dept_name,avg_salary)
where avg_salary > 42000;
lateral
:使 from子句访问它前面的表或者子查询中的属性目前只有少数SQL支持lateral
,如果没有lateral
子句,子查询就不能访问来自外层查询的相关变量I1。
select name,salary,avg_salary
from instructor I1,lateral(select avg(salary) as avg_salary
from instructor I2
where I2.dept_name = I1.dept_name);
with
:提供定义临时关系的方法,只对包含with
子句的查询有效
找出具有最大预算值的系
with max_budget(value)as
(select max(budget)
from department)
select budget
from department,max_budget
where department.budget = max_budget.value;
SQL允许子查询出现在返回单个值的表达式能够出现的任何地方,只要该子查询只返回包含单个属性的单个元组。
列出所有的系以及他们拥有的教师数
select dept_name
(select count(*)
from instructor
where department.dept_name = instructor.dept_name)
as num_instructors
from department;