【数据库系统原理作业】七、数据查询中的嵌套查询

嵌套查询:
一个SELECT-FROM-WHERE语句称为一个查询块
将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询
例如:
select Sname
from Student
where Sno IN (select Sno
			  from SC
			  where Cno='2');
-------------------------------------------------
SQl语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询
但子查询中不能使用ORDER BY子句

一、带有IN谓词的子查询

例1.查询与“刘晨”在同一个系学习的学生。
方法一:不相关子查询

select Sno,Sname,Sdept
from Student
where Sdept in(
				select Sdept
				from Student
				where Sname='刘晨');

方法二:相关子查询

select S1.Sno,S1.Sname,S1.Sdept
from Student S1,Student S2
where S1.Sdept=S2.Sdept and
	S2.Sname='刘晨';

例2.查询选修了课程名为“信息系统”的学生学号和姓名
方法一:不相关子查询

select Sno,Sname
from Student
where Sno in(select Sno
			 from SC
			 where Cno in(select Cno
			 			  from Course
			 			  where Cname='信息系统'));

方法二:连接查询

select Sno,Sname
from Student,SC,Course
where Student.Sno =SC.Sno and
	  SC.Cno = Course.Cno and
	  Course.Cname='信息系统';	

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

当能确切知道内层查询返回单值时,可用比较运算符>,<,=,>=,<=,!=

例.找出每个学生超过他选修课程平均成绩的课程号。

select Sno,Cno
from SC
where Grade >= (select AVG(Grade)
				from SC y
				where y.Sno=x.Sno);

三、带有ANY(SOME)或ALll谓词的子查询

=<>或!=<<=>>=
ANYIN<MAX<=MAX>MIN>=MIN
ALLNOT IN<MIN<=MIN>MAX>=MAX

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

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';

例2.查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄。

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';

四、带有EXIST谓词的子查询

EXISTS谓词
	存在量词(左右翻转的E)
带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值"true"或逻辑假值"false"
1.若内层查询结果为非空,外层where句子返回真值
2.若内层查询结果为空,则外层的where子句返回假值
--NOT EXISTS与EXISTS相反
由于EXISTS引出的子查询,其目标列表表达式通常都用*,
因为带EXISTS的子查询值返回真值或假值,给出列名无实际意义。

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

select Sname
from Student
where exists(
		select *
		from SC
		where Sno=Student.Sno and Cno='1');

执行结果:
在这里插入图片描述

例2.查询没有选修1号课程的学生姓名。

select Sname
from Student
where not exists(select*
				 from SC
				 where Sno=Student.Sno and Cno='1');

执行结果:
在这里插入图片描述

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

select Sno,Sname,Sdept
from Student S1
where exists(select *
			 from Student S2
			 where S2.Sdept = S1.Sdept and
			 S2.Sname = '刘晨');

执行结果:
在这里插入图片描述

用EXISTS/NOT EXISTS实现全程量词
SQL语言中没有全称量词
可以通过下面的式子将全称量词转换为否定和存在量词
在这里插入图片描述

例4.查询选修了全部课程的学生姓名。

select Sname
from Student
where not exists(select *
				 from Course
				 where not exists(select *
				 				  from SC
				 				  where Sno=Student.Sno
				 				  and Cno=Course.CNo
				 				)
				 );

我的表里没有全选的就不输出结果了

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

select distinct Sno
from SC SCX
where not exists(select*
				 from SC SCY
				 where SCY.Sno = '201215122' and 
				 not exists(select *
				 			from SC SCZ
				 			where SCZ.Sno=SCX.Sno and
				 			SCZ.CNO=SCY.CNO));

执行结果:
在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值