一、概念描述

在SQL语言中,一个 SELECT-FROM-WHERE 语句称为一个查询块。将一个查询块嵌套在另一个查询块的 WHERE 子句或 HAVING 短语的条件中的查询称为 嵌套查询。例如:

SELECT Sname  /*外层查询或父查询*/
FROM Student
WHERE Sno IN
(SELECT Sno /*内层查询或子查询*/
FROM SC
WHERE Cno='');

SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。

注意:子查询的SELECT语句中不能使用 ORDER BY 子句,因为 ORDER BY 子句只能对最终查询结果排序。

二、带有IN谓词的子查询

在嵌套查询中,子查询的结果往往是一个集合,所以谓词 IN 是嵌套查询中最经常使用的谓词。

查询与“刘晨”在同一个系学习的学生

SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname='刘晨');

查询选修了课程名为“信息系统”的学生学号和姓名

SELECT Sno,Sname /*最后在Student关系中取出Sno和Sname*/
FROM Student
WHERE Sno IN
(SELECT Sno /*然后在SC关系中找出选修了3号课程的学生学号*/
FROM SC
WHERE Cno IN
(SELECT Cno /*首先在Course关系中找出“信息系统”的课程号,结果为3号*/
FROM Course
WHERE Cname='信息系统'
)
);

本查询同样可以用连接查询实现:

SELECT Student.Sno,Sname
FROM Student,SC,Course
WHERE Student.Sno=SC.Sno AND
SC.Cno=Course.Cno AND
Course.Cname='信息系统';

三、带有比较运算符的子查询

带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户能确切知道内层查询返回的是单个值时,可以用 >、<、=、>=、<=、!=、或<>等比较运算符。

找出每个学生超过他自己选修课程平均成绩的课程号

SELECT Sno,Cno
FROM SC X
WHERE Grade >=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);

四、带有ANY(SOME)或ALL谓词的子查询

子查询返回单值时可以用比较运算符,但返回多值时要用ANY(有的系统用SOME)或ALL谓词修饰符。而使用ANY或ALL谓词时则必须同时使用比较运算符。其语义如下:

>ANY

大于子查询结果中的某个值

>ALL

大于子查询结果中的所有值

<ANY

小于子查询结果中的某个值

<ALL

小于子查询结果中的所有值

>=ANY

大于等于子查询结果中的某个值

>=ALL

大于等于子查询结果中的所有值

<=ALL

小于等于子查询结果中的所有值

<=ANY

大于等于子查询结果中的某个值

=ANY

等于子查询结果中的某个值

=ALL

等于子查询结果中的所有值(通常没有实际意义)

!=(或<>)ANY

不等于子查询结果中的某个值

!=(或<>)ALL

不等于子查询结果中的任何一个值

查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄

SELECT Sname,Sage
FROM Student
WHERE Sage<ANY (SELECT Sage
FROM Student
WHERE Sdept='CS')
AND Sdept <> 'CS';

查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名和年龄

SELECT Sname,Sage
FROM Student
WHERE Sage<ALL
(SELECT Sage
FROM Student
WHERE Sdept='CS')
AND Sdept <> 'CS';

提示:本查询同样可以用聚集函数实现

SELECT Sname,Sage
FROM Student
WHERE Sage <
(SELECT MIN(Sage)
FROM Student
WHERE Sdept='CS')
AND Sdept <>'CS';

在此把ANY、ALL与聚集函数的对应关系表示如下

五、带有 EXISTS 谓词的子查询

带有EXISTS 谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。

查询所有选修了1号课程的学生姓名

SELECT Sname
FROM Student
WHERE EXISTS
(SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='');

使用存在量词EXISTS后,若内层查询结果为空,则外层的WHERE子句返回真值,否则返回假值。

查询没有选修1号课程的学生姓名

SELECT Sname
FROM Student
WHERE NOT EXISTS
(SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='');

查询选修了全部课程的学生姓名

由于没有全称量词,可将题目的意思转换成等价的用存在量词的形式:查询这样的学生,没有一门课程是他不选修的。

SELECT Sname
FROM Student
WHERE NOT EXISTS
(SELECT *
FROM Course
WHERE NOT EXISTS
(SELECT *
FROM SC
WHERE Sno=Student.Sno
AND Cno=Course.Cno));

查询至少选修了学生201215122选修的全部课程的学生号码

SELECT DISTINCT Sno
FROM SC SCX
WHERE NOT EXISTS
(SELECT *
FROM SC SCY
WHERE SCY.Sno='' AND
NOT EXISTS
(SELECT *
FROM SC SCZ
WHERE SCZ.Sno=SCX.Sno AND
SCZ.Cno=SCY.Cno));

六、总结

此次学习和整理了有关SQL与嵌套查询相关的程序

  • 带有IN谓词
  • 带有比较运算符
  • 带有ANY或ALL
  • 带有EXISTS谓词

尤其应格外重视 ANY、ALL与聚集函数的对应关系,还有带EXISTS时逻辑上的判断。

最新文章

  1. storage disk
  2. Application中的路径
  3. 单向和双向tvs管
  4. java日志框架与日志系统
  5. Entity Framework 的事务
  6. 关于CKEditor.NET的安全性错误
  7. 程序员需要有多懒 ?- cocos2d-x 数学函数、常用宏粗整理 - by Glede
  8. rsync+inotify实现文件同步更新(配置)
  9. C#使用ServiceStack读写Redis
  10. Java编程题(1):n个数里出现次数大于等于n/2的数
  11. MySQL数据命令
  12. 无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-|1-1-0.dll
  13. Linux内核跟踪之syscall tracer 【转】
  14. 【PHP】算法进阶,获取给定值的最优组合:虚拟币抵扣问题解决方案
  15. Git 学习记录一
  16. 关于找不到stdafx.h头文件问题(pass)
  17. 人脸对齐SDM原理----Supervised Descent Method and its Applications to Face Alignment
  18. Linux下cacti的安装
  19. P2754 [CTSC1999]家园
  20. password &amp; Encryption

热门文章

  1. docker使用示例
  2. Python获取间隔时间段的时间戳数据
  3. 带网上开户表单jQuery焦点图
  4. [转]Mustache 使用心得总结
  5. SpringBoot使用AutoConfiguration自定义Starter
  6. PHP只显示姓名首尾字符,隐藏中间字符并用*替换
  7. Spirng MVC启动流程
  8. 了解PHP中$_SERVER变量对路径的解析
  9. git commit 合并
  10. 关于OpenVR