准备数据

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

student数据表:

course数据表:

sc数据表:

EXISTS

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

一个例子1.1:

要求:查询选修了课程”操作系统“的同学

SQL语句:

  1. SELECT Sname FROM student
  2. WHERE EXISTS
  3. (SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系统")
SELECT Sname FROM student
WHERE EXISTS
(SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系统")

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

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

  1. SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系统"
SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系统"

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

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

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

查询结果表:

NOT EXISTS

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

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

SQL语句:

  1. SELECT Sname FROM student
  2. WHERE NOT EXISTS
  3. (SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系统")
SELECT Sname FROM student
WHERE NOT EXISTS
(SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系统")

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

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

查询结果表:

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

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

SQL语句:

  1. SELECT Sname
  2. FROM Student
  3. WHERE NOT EXISTS
  4. (SELECT * FROM Course WHERE NOT EXISTS
  5. (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)
  6. );
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表中的第一条记录是李勇同学对应的记录,然后中间层的course表的第一条记录是数据库对应的记录,然后对该数据进行判断(最内层的WHERE语句),结果返回真,则内层的NOT EXISTS为假,

然后继续对course表中的下一条记录进行判断,返现NOT EXISTS的值也为假,直到遍历完course表中的所有的数据,内层的NOT EXISTS的值一直都是假,所以中间层的WHERE语句的值也一直都是假。

对应student的李勇记录,course表中的所有的记录对应的中间层的返回值为假,所以最外层的NOT EXISTS对应的值为真,最外层的WHERE的值也为真,则李勇对应的记录符合查询条件,装入结果表中。

然后继续对student表中的下一条记录进行判断,直达student表中的所有数据都遍历完毕。

查询结果表:

MySQL中的exist与not exists的更多相关文章

  1. MySQL中实现DROP USER if EXISTS `test`,即创建新用户时检测用户是否存在

    MySQL中实现DROP USER if EXISTS `test`,即创建新用户时检测用户是否存在    版权声明:本文为博主原创文章,欢迎大家转载,注明出处即可.有问题可留言,会尽快回复,欢迎探讨 ...

  2. mysql中/*!40000 DROP DATABASE IF EXISTS `top_server`*/;这中注释有什么作用?

    需求描述: 今天在进行mysqldump实验,使用--add-drop-databases参数,于是在生成的SQL文件中,就出现了. /*!40000 DROP DATABASE IF EXISTS ...

  3. (转)MySQL中In与Exists的区别

    背景:总结mysql相关的知识点. 如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件. select * from user where exists s ...

  4. MySQL中insert ignore into, on duplicate key update,replace into,insert … select … where not exist的一些用法总结

    在MySQL中进行条件插入数据时,可能会用到以下语句,现小结一下.我们先建一个简单的表来作为测试: CREATE TABLE `books` ( `id` ) NOT NULL AUTO_INCREM ...

  5. MySql中in和exists效率

    mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的 ...

  6. 浅析MySQL中exists与in的使用

    exists对外表用loop逐条查询,每次查询都会查看exists的条件语句,当 exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录, ...

  7. mysql中in和exists二者的区别和性能影响

    mysql查询语句in和exists二者的区别和性能影响 还记得一次面试中被人问到in 和 exists的区别,当然只是草草做答,现在来做下分析. mysql中的in语句是把外表和内表作hash 连接 ...

  8. 浅析MySQL中exists与in的使用 (写的非常好)

    转自http://sunxiaqw.blog.163.com/blog/static/990654382013430105130443/ exists对外表用loop逐条查询,每次查询都会查看exis ...

  9. 浅析mysql中exists 与 in 的使用

    一.exists的使用    exists对外表用loop逐条查询,每次查询都会查看exists的条件语句,当exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返 ...

随机推荐

  1. springboot mongodb jpa常用方法整理

    官方文档https://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/index.html 查询: ***** ...

  2. Mysql主从分离介绍及实现

    参考: http://www.cnblogs.com/panxuejun/p/5887118.html https://www.cnblogs.com/alvin_xp/p/4162249.html ...

  3. 如何给Word参考文献加方括号

    脚注是在页面下端添加的注释,如添加在一篇论文首页下端的作者情况简介:尾注是在文档尾部(或节的尾部)添加的注释,如添加在一篇论文末尾的参考文献目录. 若用手工添加脚注和尾注,则既麻烦又易出错.当用Wor ...

  4. vagrantfile 配置

    config.vm.network "forwarded_port", guest: 22, host: 2222, id: "ssh", disabled: ...

  5. Java定义队结构,实现入队、出队操作

    package com.example.demo; import java.util.ArrayList; public class Queue { ArrayList<Object> l ...

  6. 记录一次维护weblogic集群的问题

    [问题描述] weblogic 集群子服务节点启动,启动完毕后状态改为 ADMIN,正常情况是 RUNNING 在启动脚本添加如下配置即可 -DDomainRegistrationEnabled=tr ...

  7. c++ easyX的学习

    画象棋盘来浅显学习了解easyx 了解象棋盘的构成: 如图就为一个基本的象棋棋盘我们下面就用esayx来画出这个棋盘,我的感觉这个棋盘大概分为两个部分:第一部分就是棋盘的大致布局,第二个就是棋盘的细节 ...

  8. Cuda9.0安装

    CUDA 9.0安装笔记 最近实验室新购买两块K80的GPU.作为好奇的小猪,当然会自报奋勇去配置环境.在这篇博客中将会介绍在centos7下配置CUDA 9.0的步骤. 1. 什么是CUDA? 引用 ...

  9. 使用cordova调用相机在相机中添加蒙版

    变态的需求,要在cordova调起得相机上加入一拍照的轮廓,在cordova的插件中拿不到拍照的方法,起初选用UIImagePickerController的cameraOverlayView属行,结 ...

  10. iOS中为控件设置颜色渐变和透明度渐变

    项目中用到地图设置渐变色,查找资料找到两种方法:一种设置颜色,一种设置透明度: //为颜色设置渐变效果: UIView *view = [[UIView alloc] initWithFrame:CG ...