数据操作--子查询
1、在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。
2、子查询是一个 SELECT 查询,它嵌套在语句的 WHERE 或 HAVING 子句内,或其它子查询中
3、子查询的 SELECT 查询总用圆括号括起来。
(1)使用子查询进行基于集合的测试
使用子查询进行基于集合的测试的语句的一般格式为: 列名 NOT IN (子查询)
例2、 查询选修了“数据库基础”课程的学生的学号、姓名。
SELECT Sno, Sname FROM Student WHERE Sno IN ( SELECT Sno FROM SC WHERE Cno IN (SELECT Cno FROM Course WHERE Cname = '数据库基础') )
(2)使用子查询进行比较测试
1)带比较运算符的子查询指父查询与子查询之间用比较运算符连接。
2)能确切知道内层查询返回的是单值时,可用>、<、=、>=、<=、<>运算符。
例3:查询修了‘c02’课程且成绩高于此课程的平均成绩的学生的学号和成绩。
SELECT Sno , Grade FROM SC WHERE Cno = 'c02‘ and Grade > ( SELECT AVG(Grade) from SC WHERE Cno = 'c02')
(3)带有ANY(SOME)或ALL谓词的子查询
谓词语义 ANY:任意一个值 ALL:所有值
需要配合使用比较运算符
例4:查询其他系中比计算机系某一学生年龄小的学生姓名和年龄
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 < (SELECT MAX(Sage) FROM Student WHERE Sdept= ‘CS ') AND Sdept <> ' CS ’;
例4:查询其他系中比计算机科学系所有学生年龄都小的学生姓名及年龄。
方法一:用ALL谓词 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 ’;
(4)使用子查询进行存在性测试
EXISTS谓词: 带EXISTS谓词的子查询不返回查询的数据,只产生逻辑真值(有数据)和假值(没有数据)。
1. EXISTS谓词 存在量词 带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”,判断有无结果。 若内层查询结果为空,则外层的WHERE子句返回假值 若内层查询结果非空,则外层的WHERE子句返回真值 因带EXISTS的子查询只返回true或false,给出列名无实际意义,通常都用* 。
2. NOT EXISTS谓词 若内层查询结果非空,则外层的WHERE子句返回假值 若内层查询结果为空,则外层的WHERE子句返回真值
例5:查询选修了‘c01’号课程的学生姓名。 SELECT Sname FROM Student WHERE EXISTS (SELECT * FROM SC WHERE Sno = Student.Sno AND Cno = 'c01')
2点注意
注1:处理过程为:先外后内;由外层的值决定内层的结果;内层执行次数由外层结果数决定。
注2: 由于EXISTS的子查询只能返回真或假值,因此在这里给出列名无意义。所以在有EXISTS的子查询中,其目标列表达式通常都用*。
例6:查询没有选修‘c01’号课程的学生姓名和所在系。 SELECT Sname, Sdept FROM Student WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno = Student.Sno AND Cno = 'c01')
不同形式的查询间的替换
- 一些带EXISTS或NOT EXISTS谓词的子查询不能被其他形式的子查询等价替换。
- 所有带IN谓词、比较运算符、ANY和ALL谓词的子查询都能用带EXISTS谓词的子查询等价替换。
例7:查询选修了全部课程的学生姓名。
SELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno) );
查询学生X,对于学生X来说,不存在课程y,200215122选修了y,而学生x没有选。用NOT EXISTS谓词表示:
SELECT DISTINCT Sno FROM SC SCX WHERE NOT EXISTS (SELECT * FROM SC SCY WHERE SCY.Sno=‘200215122‘ AND not exists (SELECT * FROM SC SCZ WHERE SCZ.Sno=SCX.Sno AND SCZ.Cno=SCY.Cno) );
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!