为什么exists谓词常用于进行相关sql 子查询 exists

3561人阅读
Oracle(32)
EXISTS代表存在量词 。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
例如:三个表:
student(sno,sname,ssex,sage,sdept)(学号,姓名,性别,年龄,专业)
course(cno,cname,cpno,ccredit)(课程号,课程名,选修课号,学分)
sc(sno,cno,grade)(学号,课程号,成绩)
&1、 查询所有选修了1号课程的学生姓名。
本题涉及student和sc表。可以在student中一次取得每个元组的sno值,用此值去检查sc表。若sc表存在这样的元组,其sno值等于此student.sno值,并且其cno='1',则取此student.sname送入结果表。将此想法写成sql语句是:
select sname&from student
where exists (
&& select *
&&& from sc
&&& where sno=student.sno and cno='1'
使用存在量词exists后,若内层查询结果非空,则外层的where子句返回真值,否则返回假值。由于exists引出的子查询,其目标列表达式通常用*,因为带exists的子查询只返回真值或假值,给出列名无实际意义。
本例中子查询的查询条件依赖于外层父查询的某个属性值(在本例中是student的sno值),因此也是相关子查询。这个相关子查询的处理过程是:首先取外层查询中(student)表的第一个元组,根据它与内层查询相关的属性值(sno值)处理内层查询,若where子句返回值为真,则取外层查询中该元组的sname放入结果表;然后再取(student)表的下一个元组;重复这一过程,直至外层(student)表全部检查完为止。
&&&&&&& 与exists谓词相对应的是not exists谓词。使用存在量词not exists后,若内层查询结果为空,则外层的where子句返回真值,否则返回假值。
2、查询没有选修1号课程的学生姓名
&& select sname from student
&& where not exists (
&&& select * from sc sno=student.sno and cno='1'
一些带exists或not exists 谓词的子查询不能被其他形式的子查询等价替换,但所有带in谓词、比较运算符、any和all谓词的子查询都能用带exists谓词的子查询等价替换。
&&&&&&& 由于带EXISTS量词的相关子查询只关心内层查询是否有返回值,并不需要查具体值,因此其效率并不一定低于不相关子查询,有时是高效的方法。
SQL中没有全称量词
SQL中也没有蕴含逻辑运算,可以用谓词演算将其转换为:
1、查询选修了全部课程的学生姓名
2、查询至少选修了学生95002选修的全部课程的学生号码
1、没有全称量词,将其转换为等价的用存在量词的形式:查询这样的学生,没有一门课是他不选的。
select sname
from student
where not exists(
&&&&&& select *
&&&&&& from course
&&&&&& where not exist(
&&&&&&&&&&&&& select *
&&&&&&&&&&&&& from sc
&&&&&&&&&&&&& where sc.sno = student.sno
&&&&&&&&&&&&& and cno = o
2、本查询用逻辑蕴含表达:查询学号为x的学生,对所有的课程y,只要95002学生选了课程y,则x也选了y。形式化表示如下
用p表示:学生95002选了课程y
用q表示:学生x选了课程y
转换为等价形式:
它表示的语义为:不存在这样的课程y,学生95002选了,而学生x没有选,sql如下:
select distinct sno
from sc scx
where not exists(
&&&&&& select *
&&&&&& from sc scy
&&&&&& where sno='95002'
&&&&&& and not exist(
&&&&&&&&&&&&& select *
&&&&&&&&&&&&& from scz
&&&&&&&&&&&&& where scz.sno = scx.sno
&&&&&&&&&&&&& o))&&
1.用EXISTS/NOT EXISTS实现全称量词
SQL语言中没有全称量词&(For
all),可以把带有全称量词的谓词转换为等价的带有存在量词的谓词:
&&&& &&&&&&&&&& (x)P??
($x(P))&& :含义&& (x)P表示个体域里的所有个体都有性质P。?
($x(P))&表示不存在着个体域中的个体没有性质P。
&例&查询选修了全部课程的学生姓名。
&&&&&&& SELECTSname
&&&&&&&& FROM Student
&&&&&&&& WHERE NOT EXISTS
&&&&&&&&&&& (SELECT *
&&&&&&&&&& &&&FROM Course
&&&&&&&&&&&&& WHERE NOT EXISTS
&&&&&&&&&&&&&&&&&(SELECT *
&&&&&&&&&&&&&&&&&&FROM SC
&&&&&&&&&&&&&&&&&&WHERE
Sno= Student.Sno
&&&&&&&&&&&&&&&&&&&&&AND
Cno= o);
2.用EXISTS/NOT EXISTS实现逻辑蕴函
SQL语言中没有蕴函(Implication)逻辑运算可以利用谓词演算将逻辑蕴函谓词等价转换为:
&&&&&&&&&&&&&&&&&&p(R)q??p∨q
例&查询至少选修了学生95002选修的全部课程的学生号码。
解题思路:
用逻辑蕴函表达:查询学号为x的学生,对所有的课程y,只要95002学生选修了课程y,则x也选修了y。
形式化表示:
&&&&&& &&&用P表示谓词 “学生95002选修了课程y”
&&&&&& &&&用q表示谓词 “学生x选修了课程y”
则上述查询为:& (y) p(R)
等价变换:
&&& &&&&&&&&& (y) p(R)
q?? ($y (?
&&&&&&&&&&&&&& &&&&&&&?? ($y
(?(?p∨ q))
&&&&&&&&&&&&&& &&&&&&&??$y(p∧?q)
变换后语义:不存在这样的课程y,学生95002选修了y,而学生x没有选。
用NOT EXISTS谓词表示:&&&&
&&& SELECT DISTINCTSno
&&&&&&&& FROM SC SCX
&&&&&&&& WHERE NOT EXISTS
&&&& &&&&&&&&&&(SELECT *
&&&&&&&&&&&&&&& FROM SC SCY
&&&&&&&&&&&&&&& WHERE
SCY.Sno = ' 95002 '&AND
&&&&&&&&&&&&&&&&&&&&NOT EXISTS
&&&&&&&&&&&&&&&&&&&&&&&&&(SELECT *
&&&&&&&&&&&&&&&&&&&&&&&&&&FROM SC SCZ
&&&&&&&&&&&&&&&&&&&&&&&&&&WHERESCZ.Sno=SCX.Sno AND
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&o=o));
& 含义&& (x)P表示个体域里的所有个体都有性质P。? ($x(P))&表示不存在着个体域中的个体没有性质P。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:600731次
积分:7473
积分:7473
排名:第2027名
原创:233篇
转载:94篇
评论:56条
(1)(2)(8)(7)(2)(1)(6)(10)(6)(4)(11)(9)(20)(50)(7)(26)(14)(8)(5)(14)(7)(7)(2)(5)(7)(9)(16)(6)(25)(13)(11)(1)(4)(1)(2)
NHibernate之旅【图文】数据库原理第3章_子查询_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
数据库原理第3章_子查询
上传于||暂无简介
大小:169.50KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢&exists 子查询
exists 子查询
开通极客学院VIP会员,免费观看全部会员课程
最低 21.6 元 / 月
VIP会员尊享特权
观看全部会员课程
720P高清视频下载
已有会员账号,请
视频太卡?试试切换线路
本课时介绍如何使用带有 in 谓词的子查询,该查询是判断一个表中指定列的值是否包含在子查询查出的列表中。
本课时介绍子查询,是指父查询与子查询之间用比较运算符进行连接的查询。
本课时介绍使用子查询代替表达式完成查询。
本课时介绍使用 exists 谓词来完成子查询,该子查询的作用是测试子查询返回的数据行是否存在。
只有成为VIP会员才能提问&回复,快吧!如果你还没有账号你可以一个账号。
添加新技术问题
课程 [exists 子查询]
中已存在问题
添加新技术问题
问题描述越详细,被解答的速度越快
有新回答时请邮件提醒我
着急,拜托快点
不急,慢慢解决
关联课程 [exists 子查询]
服务热线:400-678-8266Exists,NOT EXISTS:
1.含义:带有exists谓词的子查询不返回任何实际数据,它只产生逻辑真值true或逻辑假值false。
2.查询所有选修了c1号课程的学生姓名:
&& select sn from s where exists (select * from sc where sno=s.sno and cno='c1')
注:若内查询结果(select * from sc where sno=s.sno and cno='c1')为空,则外层的where子句返回真值,否则返回假值!
查询过程:步骤一:从外层查询中的s表的第一个元组,根据它,与内层查询相关的属性值(sno值)处理内层查询,若where查询子句返回值为真(及内层查询非空),则取此元组放入结果表;
&&&&&&&&&&&&&&&& 步骤二:& 在检查s表中下一个元组;
&&&&&&&&&&&&&&&& 步骤三:重复这一过程,直至s表全部检查完毕为止!
3。查询所有未修c1课程的学生姓名:
&& select sn from s where not exists (select * from sc where sno=s.sno and cno='c1')
4.查询与&王林&在同一系学习的学生的信息
&& select * from s s1 where exists (select * from s s2 where s2.dept=s1.dept and s2.sn='王林')
5.查询选修了全部课程的学生的姓名
&& select sn from s where not exists(select * from c where not exists(select * from sc where sno=s.sno and o))
数据库表s,c,sc截图请到:
阅读(...) 评论()

我要回帖

更多关于 thinkphp exists 查询 的文章

 

随机推荐