嵌套查询
定义
一个SELECT-FROM语句为一个查询块
每一个查询块返回一个元组集和,这个查询块也可以用在其他查询块中
被嵌入的查询块叫做子查询,被嵌入的查询块叫做父查询
可嵌入的子句:WHERE,HAVING,FROM
嵌入FROM :基于派生表的查询
嵌入WHERE,HAVING :嵌套查询
基于派生表的查询
子查询的结果集可以和基本关系一样作为查询的数据源,
不过需要对结果集命名以便引用
\textcolor{red}{不过需要对结果集命名以便引用}
不过需要对结果集命名以便引用
例子
SELECT S.Sno,Sname,avg_grade
FROM S,
(SELECT Sno,AVG(Grade) AS avg_grade
FROM SC
GROUP BY Sno
) AS SC_AVG
WHERE S.sno=SC_AVG.Sno
嵌套查询
将一个查询块嵌套在另外一个查询块的WHERE子句或者HAVING短语的条件中的查询
带有谓词IN的查询
查询与’刘晨’在同一个系学习的学生
1.确定刘晨所在系
SELECT Sdept
FROM S
WHERE Sname='刘晨';
2.查找所有在IS系学习的学生
SELECT Sno,Sname,Sdept
FROM S
WHERE Sdept IN ('IS');
3.将1嵌入2中得
SELECT Sno,Sname,Sdept
FROM S
WHERE Sdept IN
(
SELECT
FROM S
WHERE Sname='刘晨'
);
先执行子查询,得到结果集{‘IS’}
再执行父查询
这种
子查询的执行不需要依赖父查询的嵌套查询称为不相关子查询
\textcolor{red}{子查询的执行不需要依赖父查询的嵌套查询称为不相关子查询}
子查询的执行不需要依赖父查询的嵌套查询称为不相关子查询
带有比较运算符的子查询
当能确切知道内层查询返回一个
单值
\textcolor{red}{单值}
单值
时,可以用比较运算符(>,<.=,>=,<=,<>,!=),
子查询一定要放在运算符号之前
\textcolor{red}{子查询一定要放在运算符号之前}
子查询一定要放在运算符号之前
找出这样的学号和课程号:该生选修这门课的成绩超过他所有选修课的平均成绩
SELECT Sno,Cno
FROM SC AS X
WHERE Grade>=(SELECT AVG(Grade)
FROM SC AS Y
WHERE X.Sno=Y.Sno
);
该查询为
相关子查询
\textcolor{red}{相关子查询}
相关子查询
带有SOME,ALL谓词的子查询
需要配合比较运算符使用
谓词 | 作用 |
---|---|
>SOME | 大于子查询结果的某个值 |
>ALL | 大于子查询结果的所有值 |
<SOME | 小于子查询结果的某个值 |
<ALL | 大于子查询结果的所有值 |
>=SOME | 大于等于子查询结果的某个值 |
>=ALL | 大于等于子查询结果的所有值 |
<=SOME | 小于等于子查询结果的某个值 |
>=ALL | 大于等于子查询结果的所有值 |
=SOME | 等于子查询结果的某个值 |
=ALL | 等于子查询结果的所有值 |
<> SOME | 不等于子查询结果的某个值 |
<> ALL | 不等于子查询结果的所有值 |
其他系中比信息系某些学生年龄小的学生姓名和年龄
SELECT Sname,Sage,
FROM S
WHERE Sage<SOME(SELECT Sage
FROM S
WHERE Sdept='IS'
) AND Sdept<>'IS';
带有EXISTS谓词的子查询
带有EXISTS的子查询不返回数据,之返回逻辑值 ‘true’或’false’
若内层结果为空 返回false
若内层结果不为空 返回true
查询所有选修了c1课程的学生姓名
SELECT Sname
FROM S
WHERE EXISTS(SELECT *
FROM SC
WHERE Sno=S.Sno AND Cno='C1'
);
小结
1.嵌套查询分为相关子查询和不相关子查询
2.子查询的属性不会出现在父查询的输出上
3.子查询不能使用ORDER BY,ORDER BY语句只能对最终结果排序