SQL 子查询 EXISTS 和 NOT EXISTS[通俗易懂]

SQL 子查询 EXISTS 和 NOT EXISTS[通俗易懂]MySQLEXISTS和NOTEXISTS子查询语法如下:SELECT…FROMtableWHEREEXISTS(subquery)该语法可以理解为:将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE或FALSE)来决定主查询的数据结果是否得以保留。MySQLEXISTS子查询实例下面以实际的例子来理解EXISTS子查询。下面是原始的数据表:art

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

MySQL EXISTS 和 NOT EXISTS 子查询语法如下:

  • SELECT … FROM table WHERE EXISTS (subquery)

该语法可以理解为:将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE 或 FALSE)来决定主查询的数据结果是否得以保留。

MySQL EXISTS 子查询实例

下面以实际的例子来理解 EXISTS 子查询。下面是原始的数据表:

article 文章表:

aid title content uid
1 文章1 文章1正文内容… 1
2 文章2 文章2正文内容… 1
3 文章3 文章3正文内容… 2
4 文章4 文章4正文内容… 4

user 用户表:

uid title content
1 admin admin@5idev.com
2 小明 xiao@163.com
3 Jack jack@gmail.com

我们要查出 article 表中的数据,但要求 uid 必须在 user 表中存在。SQL 语句如下:

  • SELECT * FROM article WHERE EXISTS (SELECT * FROM user WHERE article.uid = user.uid)

返回查询结果如下:

aid title content uid
1 文章1 文章1正文内容… 1
2 文章2 文章2正文内容… 1
3 文章3 文章3正文内容… 2

从语句执行结果可以看出,article 表中第 4 条记录没有被保留,原因就是该条记录的数据在子查询中返回的结果是 FALSE 。
当上面的 SQL 使用 NOT EXISTS 时,查询的结果就是 article 表中 uid 不存在于 user 表中的数据记录。

下面来三张表的实例

我们先介绍下使用的3个数据表:

student数据表:

sno 学号 sname ssex sage
20161181 Altair 20
20161182 Desmond 18
20161183 Ezio 22
20161184 Christina 19

course数据表:

cno 课程编号 cname 课程名
1 C语言
2 数据结构
3 信号与系统
4 模拟电子技术
5 高数

sc数据表:

sno 学号 cno 课程编号 grade 成绩
20161181 1 99
20161182 2 98
20161181 2 97
20161181 3 95
20161184 3 92
20161181 4 90
20161181 5 88
20161183 5 58

EXISTS

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

一个例子1.1:

要求:查询选修了课程”信号与系统“的同学

SELECT s.Sname FROM student s
WHERE EXISTS  
(SELECT * FROM sc, course c WHERE sc.sno = s.sno AND sc.cno = c.cno AND c.cname = '信号与系统')

Jetbrains全家桶1年46,售后保障稳定

使用存在量词EXISTS后,若内层查询结果为非空,则外层的WHERE子句返回值为真,否则返回值为假。

在本例中,首先分析最内层的语句:

SELECT * FROM sc, course c WHERE sc.sno = s.sno AND sc.cno = c.cno AND c.cname = '信号与系统'

本例中的子查询的查询条件依赖于外层父查询的某个属性值(本例中的是Student的Sno值),这个相关子查询的处理过程是:

首先取外层查询中(student)表的第一个元组,根据它与内层查询相关的属性值(Sno值)处理内层查询,若外层的WHERE返回为真,则取外层查询中该元组的Sname放入结果表;

然后再取(student)表的下一组,重复这一过程,直至外层(Student)表全部检查完毕。

查询结果表:

Sname
Altair
Christina

NOT EXISTS

与EXISTS谓词相对的是NOT EXISTS谓词。使用存在量词NOT EXISTS后,若对应查询结果为空,则外层的WHERE子语句返回值为真值,否则返回假值。

例子2.1:
要求:查询没有选修课程”信号与系统“的同学

SELECT s.Sname FROM student s
WHERE NOT EXISTS  
(SELECT * FROM sc, course c WHERE sc.sno = s.sno AND sc.cno = c.cno AND c.cname = '信号与系统')

使用NOT EXISTS之后,若内层查询结果为非空,则对应的NOT EXISTS不成立,所以对应的WHERE语句也不成立。

在例子1.1中李勇同学对应的记录符合内层的select语句的,所以返回该记录数据,但是对应的NOT EXISTS不成立,WHERE语句也不成立,表示这不是我们要查询的数据。

查询结果表:

Sname
Desmond
Ezio

例子2.2(这是一个用NOT EXISTS表示全称量词的例子):

要求:查询选修了全部课程的学生姓名。

SQL语句:

SELECT Sname  
FROM Student   
WHERE NOT EXISTS  
(SELECT * FROM Course WHERE NOT EXISTS  
     (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)  
);  

这个算是一个比较复杂的sql语句了,两个EXISTS和三个WHERE。

这个sql语句可以分为3层,最外层语句,最内层语句,中间层语句。

我们很关心最外层语句,因为结果表中的数据都是最外层的查询的表中的数据,我们更关心最内层的数据,因为最内层的数据包含了全部的判断语句,决定了student表中的那一条记录是我们查询的记录。

我们由内而外进行分析:

最外层的student表中的第一条记录是Altair同学对应的记录,然后中间层的course表的第一条记录是数据库对应的记录,然后对该数据进行判断(最内层的WHERE语句),结果返回真,则内层的NOT EXISTS为假,
然后继续对course表中的下一条记录进行判断,返现NOT EXISTS的值也为假,直到遍历完course表中的所有的数据,内层的NOT EXISTS的值一直都是假,所以中间层的WHERE语句的值也一直都是假。
对应student的Altair记录,course表中的所有的记录对应的中间层的返回值为假,所以最外层的NOT EXISTS对应的值为真,最外层的WHERE的值也为真,则Altair对应的记录符合查询条件,装入结果表中。
然后继续对student表中的下一条记录进行判断,直达student表中的所有数据都遍历完毕。

下面是我自己对这段sql的解读:

先取一条student记录,进入中层,再取一条course的记录,进入内层,此时student的记录和course的记录,作为内层判断的条件,比如此时我取的第一条记录是Altair,那么我里面的Sql就可以写成

SELECT * FROM Course WHERE NOT EXISTS  
     (SELECT * FROM SC WHERE Sno = '20161181' AND Cno=Course.Cno)  
)

此处 sno 20161181即Altair的学号,这条sql的意思是选出没有被Altair选择的课程,如果不存在,则返回false,再跟最外层的NOT EXISTS关联,负负得正。每一条循环的意思就是指,筛选出的每一个学生都不存在没有被他选取的那门课,即选了所有课。

最终查询结果:

Sname
Altair
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/234114.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • icmp协议是tcp还是udp_icmp协议使用udp

    icmp协议是tcp还是udp_icmp协议使用udp2018年4月11日11:41:29更新工具发包触发点结局traceroute初始发udp包ttl递增,icmp每一跳报ttl超时udp端口不可达tracert初始发icmprequest包触发点:ttl递增,icmp超时icmpechoreply注:触发点都是根据ttl超时来检测参考项traceroutetracert…

  • Python 数据可视化,常用看这一篇就够了

    Python 数据可视化,常用看这一篇就够了文章目录前言可视化视图分为4类,散点图折线图直方图条形图箱线图饼图热力图蜘蛛图二元变量分布成对关系总结前言如果你想要用Python进行数据分析,就需要在项目初期开始进行探索性的数据分析,这样方便你对数据有一定的了解。其中最直观的就是采用数据可视化技术,这样,数据不仅一目了然,而且更容易被解读。可视化视图分为4类,比较:比较数据间各类别的关系,或者是它们随着时间的变化趋势,比如折线图;联系:查看两个或两个以上变量之间的关系,比如散点图;构成:每个部分占整体的百分比,或者是随着时间的百

  • Asp.Net MVC模型验证正则表达式[通俗易懂]

    Asp.Net MVC模型验证正则表达式[通俗易懂][RegularExpression(@”^\+?[1-9][0-9]*$”,ErrorMessage=”排序内容必须为不小于1的正整数”)][Display(Name=”排序”)]publicoverrideNullable<int>OrderNum{get;set;}参考地址mvc模型验证及正则表达式如何在MVC3正则表达式中为NOTNULL或ZERO提供数据注释验证模型验证表达式可叠加[NotNullExpression]//非空[Regula

  • Mysql java JDBC驱动jar包

    Mysql java JDBC驱动jar包mysql-connector-java-8.11.tar.gzmysql-connector-java-8.0.11.zip说明:在学习Hive时,需要用mysql存储元数据,需要用到java的mysql驱动包,需要可以拿取,都是"京斗码农",相互学习、相互贡献。链接:https://pan.baidu.com/s/1YRLx3Nle3ByG8OmmcnuODQ密码:hsq1…

  • 数据结构,计算机网络,数据库,计算机组成原理,操作系统有哪些好的网课值得推荐?[通俗易懂]

    大家好,我是小林哥。作为自学CS过来的老学长,看过中国mooc、b站、网易云课堂很多视频,期间踩了不少坑,这次掏心掏肺前来跟分享下,网上的资源是免费的,但是找到质量好的是需要时间成本的!数据结构,计算机网络,数据库,计算机组成原理,操作系统这些在大学期间一定要掌握好来,因为现在互联网大厂面试都爱考察这些内容,一句话,计算机基础,yyds!可能大家第一个问题是,这些课需要哪些先学?讲真,这些都是独立的课程,关联性不会大到说学这个课前要先学另外一个课,所以大家不要担心这个问题,它不是问题!可能大家也会

  • flashfxp注册码

    flashfxp注册码FlashFXP4.0注册码key(通用):——–FlashFXPRegistrationDataSTART——–FLASHFXPVENSVURFnQEAAAGGZJcQuuC6/Znb915ltgBNBmXkEQhOgVxpo/z4OJEIfnjjL/LLDCQbiZE9+N8EbDIQP/sQQf5D+faH6owMEG7/wINp3590f9jk462O98CWS

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号