mysql 子关联查询之 EXISTS 和 NOT EXISTS

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

SELECTFROM table WHERE EXISTS (subquery)

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

范例一:
下面以实际的例子来理解 EXISTS 子查询。下面是原始的数据表:
article 文章表:
在这里插入图片描述
user 用户表:
在这里插入图片描述
我们要查出 article 表中的数据,但要求 uid 必须在 user 表中存在。SQL 语句如下:

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

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

范例二:
我们先介绍下使用的3个数据表:
student数据表:
在这里插入图片描述
course数据表:
在这里插入图片描述
sc数据表:
在这里插入图片描述

EXISTS

EXISTS代表存在量词∃。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或者逻辑假值“false”。
查询选修了课程”信号与系统“的同学
其他方式:
还可以通过三表联查的方式查询(join)

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 = '信号与系统')

使用存在量词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)表全部检查完毕。

查询结果表:
在这里插入图片描述

NOT EXISTS

与EXISTS谓词相对的是NOT EXISTS谓词。使用存在量词NOT EXISTS后,若对应查询结果为空,则外层的WHERE子语句返回值为真值,否则返回假值。
查询没有选修课程”信号与系统“的同学

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语句也不成立。

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

查询结果表:
在这里插入图片描述
查询选修了全部课程的学生姓名:(这是一个用NOT EXISTS表示全称量词的例子)
其他方式:
可以查询sc数据表 group by sno 学号 having count (sno 学号) > course数据表全部课程的数量来查询

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表中的所有数据都遍历完毕。

先取一条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关联,负负得正。每一条循环的意思就是指,筛选出的每一个学生都不存在没有被他选取的那门课,即选了所有课。

最终查询结果:
在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL中的exists和not exists是用于判断查询中是否存在数据的关键字。 exists表示查询中存在数据时返回true,否则返回false。 not exists表示查询中不存在数据时返回true,否则返回false。 例如: SELECT * FROM table1 WHERE EXISTS (SELECT * FROM table2 WHERE table1.id = table2.id); 上述语句表示如果table2中存在与table1中id相同的数据,则返回table1中所有数据。 SELECT * FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.id = table2.id); 上述语句表示如果table2中不存在与table1中id相同的数据,则返回table1中所有数据。 ### 回答2: MySQL的"EXISTS"和"NOT EXISTS"是用于检查查询返回的结果是否为空。具体来说,"EXISTS"用于判断查询的结果集是否存在,如果存在则返回"true",否则返回"false";"NOT EXISTS"则刚好相反,如果查询的结果集不存在,则返回"true",否则返回"false"。 例如,我们有两个表:"orders"和"customers"。我们想要找出已经下过订单的顾客,可以使用"EXISTS"关键字来实现: ``` SELECT * FROM customers c WHERE EXISTS ( SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id ); ``` 上述查询语句中,首先从"customers"表中选择所有的顾客记录,并在WHERE句中使用一个查询来判断是否存在该顾客的订单记录。如果存在,则返回该顾客记录。 相反地,如果我们想要找出没有下过订单的顾客,则可以使用"NOT EXISTS"关键字: ``` SELECT * FROM customers c WHERE NOT EXISTS ( SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id ); ``` 上述查询语句中,使用"NOT EXISTS"来判断不存在顾客的订单记录,如果不存在,则返回该顾客记录。 总结来说,通过使用"EXISTS"和"NOT EXISTS"可以方便地检查查询的结果是否为空,从而实现我们所需的条件判断。在实际应用中,这些关键字可以用于复杂的查询条件,帮助我们过滤和筛选数据。 ### 回答3: MySQL中的EXISTS和NOT EXISTS是两个用于查询的谓词。它们用于判断一个查询是否返回数据,并根据返回结果进行条件判断。 EXISTS谓词用于判断一个查询是否返回任何结果。如果查询返回了至少一条数据,则表达式返回TRUE;否则返回FALSE。我们可以使用EXISTS来进行关联查询,判断某个条件是否存在。 举个例,我们可以使用EXISTS来判断是否有学生通过考试: ``` SELECT name, score FROM students WHERE EXISTS ( SELECT * FROM exam_results WHERE students.id = exam_results.student_id AND exam_results.score >= 60 ) ``` 上面的查询会返回通过考试的学生的姓名和分数。 NOT EXISTS则与EXISTS相反,用于判断查询是否没有返回任何结果。如果查询没有返回数据,则表达式返回TRUE;否则返回FALSE。我们可以使用NOT EXISTS来查询不存在某个条件的数据。 举个例,我们可以使用NOT EXISTS来查询没有购买过商品的顾客: ``` SELECT name, address FROM customers WHERE NOT EXISTS ( SELECT * FROM orders WHERE customers.id = orders.customer_id ) ``` 上面的查询会返回没有购买过商品的顾客的姓名和地址。 总之,MySQL中的EXISTS用于判断查询是否存在结果,而NOT EXISTS则用于判断查询是否不存在结果。我们可以利用这两个谓词来进行更复杂的条件查询。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值