SQL Server中的嵌套查询

本文介绍了SQL中的嵌套查询概念,包括不相关子查询与相关子查询的区别,如何使用IN、ANY/SOME、ALL等谓词进行子查询,以及带有EXISTS谓词的子查询的应用。此外还探讨了用聚集函数实现子查询的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嵌套查询

在SQL语音中,一个select-from-where语句称为一个查询块。将一个查询块嵌套在另一个查询块的where子句或HAVING短语的条件中的查询称为嵌套查询。在嵌套查询中上层的查询块称为外层查询或父查询,下层的查询块称为内层查询或子查询。

带有IN谓词的子查询
先分步来进行查询
在这里插入图片描述
然后将第一步查询嵌套在第二步查询的条件中,构造嵌套查询。

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='刘晨';

在这里插入图片描述
由此可知实现同一个查询有多种方法,只是不同方法的效率不同。

涉及三个属性的查询

SELECT Sno,Sname
FROM Student
WHERE Sno IN
	  (select Sno
	   FROM SC
       WHERE Cno IN
			 (SELECT Cno
				FROM Course
				WHERE 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 大于等于子查询结果中的所有值
<= ANY 小于等于子查询结果中的某个值
<= ALL 小于等于子查询结果中的所有值
= 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查询效率要高。

下面是ANY、ALL与聚集函数的对应关系:

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

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

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

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

在这里插入图片描述

查询选修了全部课程的学生姓名
SQL中没有全称量词(for all),但是可以把带有全称量词的谓词转换为等价的带有存在量词的谓词。

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='201215122' AND
			 NOT EXISTS
			 (SELECT*
			  FROM SC SCZ
			  WHERE SCZ.Sno=SCX.Sno AND
					SCZ.Cno=SCY.Cno));

在这里插入图片描述

本次实验到此结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值