本文主讲数据查询中的
嵌套查询(EXISTS部分)、集合查询、基于派生表的查询
,欢迎阅读~
📋简洁的目录(暗示按顺序看)
一、带有EXISTS谓词的子查询
EXISTS谓词
-
存在量词
∃ \exists
∃
-
带有EXISTS谓词的子查询
不返回任何数据
,只产生
逻辑真值“true”
或
逻辑假值“false”
若内层查询结果
非空
,则外层的
WHERE子句返回真值
若内层查询结果
为空
,则外层的
WHERE子句返回假值
- 由EXISTS引出的子查询,其目标列表达式通常都用 * ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义
NOT EXISTS谓词
(记住与EXISTS相反就行)
若内层查询结果非空,则外层的WHERE子句返回假值
若内层查询结果为空,则外层的WHERE子句返回真值
🌟
来看例子:
查询所有
选修了1号课程
的
学生姓名
:
·
理理思路:
①
选修了1号课程所以涉及SC表,学生姓名涉及Student表
②
在Student中依次取每个元组的Sno值,用此值去检查SC表
③
若SC中存在这样的元组,其Sno值等于此Student.Sno值,并且其Cno= ‘1’,则取出此Student.Sname送入结果表)
(运用相关子查询)
SELECT Sname
FROM Student
WHERE EXISTS
( SELECT *
FROM SC
WHERE Sno = Student.Sno AND Cno = '1');
ps:🙋这个题目明显也可以直接用连接查询解决,那为什么还要用EXISTS写这么多呢?
采用EXISTS谓词能
更容易理解
,而且连接查询能表达的它都能表达,但是它能表达的连接查询并不一定能表达,对于这个题来说两种方式均可,不过EXISTS的
应用范围更广
。
🌟
Another one:
查询没有选修1号课程的学生姓名:
(因为刚刚求解过选修1号课程的学生,这里直接将其否定就可以啦,采用NOT EXISTS谓词)
SELECT Sname
FROM Student
WHERE NOT EXISTS
( SELECT *
FROM SC
WHERE Sno = Student.Sno AND Cno = '1');
不同形式的查询间的替换
-
一些
带
EXISTS
或
NOT EXISTS
谓词的子查询
不能被其他形式的子查询等价替换
-
所有
带
IN
谓词、
比较运算符
、
ANY
和
ALL
谓词的子查询
都能用带EXISTS谓词的子查询等价替换
-
总结一下就是:
EXISTS比IN、比较运算符、ANY、ALL的应用范围更广,在这一层面上来说EXISTS更强一些,而且EXISTS的表达能力更强,比较容易理解
(
但是!
有时候用EXISTS没有用其他的方法方便和好用,所以该用什么得根据情况而定,这里只是说明EXISTS是能用的,不过不一定是最适合的)
🌟
来看例子:
查询与“刘晨 ”在同一个系学习的学生:
(看过我之前的博客的小伙伴应该对这个例子有印象,之前我是采用
IN谓词
和
自身连接
来解决的,详细过程和解释可康我的上一篇博客吖:
SQL Server 数据库基本操作入门篇【5】
)
SELECT Sno, Sname, Sdept
FROM Student S1
WHERE EXISTS
( SELECT *
FROM Student S2
WHERE S2.Sdept = S1.Sdept AND S2.Sname = '刘晨'); /*采用EXISTS谓词解决,且是一个相关子查询*/
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept IN
( SELECT Sdept
FROM Student
WHERE Sname = '刘晨'); /*采用IN谓词解决,且是一个不相关子查询*/
SELECT S1.Sno, S1.Sname, S1.Sdept
FROM Student S1, Student S2
WHERE S1.Sdept = S2.Sdept