数据库系统原理 数据查询之嵌套查询

本文深入探讨了SQL中的嵌套查询概念,包括不相关和相关子查询的区别,以及使用IN、比较运算符、ANY/ALL、EXISTS等谓词进行查询的技巧。通过实例讲解了如何利用嵌套查询解决复杂的数据筛选问题。

嵌套查询

  • 一个SELECT-FROM-WHERE语句称为一个查询块
  • 将一个查询块嵌套在另一个查询块的WHERE字句或HAVING短语的条件中的查询叫做嵌套查询。
  • Order by不能出现在嵌套块中。
  • 上层查询块称外层或父查询,下层称内层或子查询。
  • SQL允许多层嵌套。
按相关性(嵌套查询的求解过程)划分嵌套查询:

不相关子查询
子查询的查询条件不依赖于父查询。故有里向外逐层处理。

相关子查询
子查询的查询条件依赖于父查询。

  • 取外层查询中表的第一个元素,根据与内层查询相关的属性值处理内层查询,若Where子句返回真,则此元组放入结果表中。
  • 从外层表中取下一个元组,重复直至检查完毕。
按谓词划分嵌套查询:

1、带In谓词的子查询
In谓词即集合的所属关系。

查询与“刘晨”在同一个系学习的学生
SELECT Sno,sname,sdept
From Student
Where Sdept In
	  (Select Sdept
	   From Student
	   Where Student.Sname='刘晨')
//为不相关查询
查询选修了课程名为信息系统的学生学号和姓名。
两种方法:
一、嵌套查询
Select Sno,Sname
From Student
Where Sno in
	(Select sno
	From SC
	Where cno In
		(Select Cno
		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='信息系统'

2、带有比较运算符的子查询
当确切知道内层查询返回值为单值时,可用比较运算符

找出每个学生超过他选修课程平均成绩的课程号
Select Sno,Cno
From SC x
Where Grade>=(Select AVG(Grade)
			  From SC y
			  Where x.Sno=y.Sno)

3、带有ANY或ALL谓词的子查询
ANY:查询结果汇总任意一个值
ALL:查询结果汇总全部值
EXIST:查询结果是否为空,空返回false,不空返回true。
在这里插入图片描述

查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄。
Select Sname,sage
From Student
Where Sage<ANY(SELECT Sage
			   From Student
			   Where Sdept='CS')
	  AND Sdept<>'CS'
//<>为不等于
//如查询非计算机科学系中比计算机科学系所以一个学生年龄小的学生姓名和年龄,则将ANY改为ALL

4、带EXISTS谓词的子查询
由EXISTS引出的子查询,目标列通常为*,因为其只返回真值或假值,给出列名无意义。

查询没有选修1号课程的学生姓名。
Select Sname
From Student
Where Not EXISTS
	  (SELECT *
	   FROM SC
	   WHERE SC.Sno=Student.Sno AND Cno='1')


EXISTS/NOT EXISTS可实现全程量词(难点),例子如下:

查询选修了所有课程的学生姓名
Select Sname
From Student
Where NOT EXISTS /位置2/
	  (SELECT *
	   FROM Course
	   WHERE NOT EXISTS /位置1/ 
			(SELECT *
			 FROM SC
			 WHERE Student.Sno=SC.Sno AND
				   SC.Cno=Course.Cno))
理解:若一个学生选修了所有课程,则位置1始终为false,则位置2为true,该学生信息进入结果表
	  若一个学生漏选了某个课程,则位置1有一次为true,则位置21之间的Select有一个值,则位置2为false,信息不能进入结果表。
	  否定的否定即肯定!

EXISTS/NOT EXISTS实现逻辑蕴涵(难点
SQL中没有蕴含逻辑运算,已知蕴含谓词表达式:
在这里插入图片描述

查询至少选修了学生200215122选修的全部课程的学生。!!!!!!!!重要!我不会!
SELECT *
From Student S1
Where NOT EXISTS /位置2/
		(SELECT *
		 FROM SC S2
		 WHERE S2.Sno='200215122' AND
			NOT EXISTS /位置1/
			(
				SELECT *
				FROM SC S3
				WHERE S1.Sno=S3.Sno AND
					  S2.Cno=s3.Cno
			))
理解同上:若一个学生选修了200215122的所有课程,则位置1始终为false,则位置2为true,该学生信息进入结果表
	  	 若一个学生漏选了200215122的某个课程,则位置1有一次为true,则位置21之间的Select有一个值,则位置2为false,信息不能进入结果表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值