比如在Northwind数据库中有一个查询为

SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID)

这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID里面啊,这是如何匹配的呢? EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS 指定一个子查询,检测 行 的存在。语法:EXISTS subquery参数:subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。结果类型:Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE 。

(一). 在子查询中使用 NULL 仍然返回结果集

select * from TableIn where exists(select null)等同于:select * from Table In

(二). 比较使用 EXISTS 和 IN 的查询。注意两个查询返回相同的结果。

select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)

select * from TableIn where ANAME in(select BNAME from TableEx)

(三). 比较使用 EXISTS 和 = ANY 的查询。注意两个查询返回相同的结果。

select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)

select * from TableIn where ANAME=ANY(select BNAME from TableEx)

NOT EXISTS 的作用与 EXISTS 正好相反。如果子查询没有返回行,则满足了 NOT EXISTS 中的 WHERE 子句。结论:EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。EXISTS内部有一个子查询语句(SELECT ... FROM...), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。

例如:

1.  查询id为5的数据:  (数据存在)

 SELECT * FROM class AS c1WHERE EXISTS(SELECT class_id FROM class AS c2WHERE c1.class_id = 5);

如果exists里面返回的结果行数大于1,则返回true,则外面的查询数据可以返回。

 2.  查询id为10的数据:  (数据不存在)

SELECT * FROM class AS c1WHERE EXISTS(SELECT class_id FROM class AS c2WHERE c1.class_id = 10);

因为exsits始终返回的是false,所以外层查询始终无效,也就不会产生数据

分析器会先看语句的第一个词,当它发现第一个词是SELECT关键字的时候,它会跳到FROM关键字,然后通过FROM关键字找到表名并把表装入内存。接着是找WHERE关键字,如果找不到则返回到SELECT找字段解析,如果找到WHERE,则分析其中的条件,完成后再回到SELECT分析字段。最后形成一张我们要的虚表。

WHERE关键字后面的是条件表达式。条件表达式计算完成后,会有一个返回值,即非0或0,非0即为真(true),0即为假(false)。同理WHERE后面的条件也有一个返回值,真或假,来确定接下来执不执行SELECT。

分析器先找到关键字SELECT,然后跳到FROM关键字将STUDENT表导入内存,并通过指针找到第一条记录,接着找到WHERE关键字计算它的条件表达式,如果为真那么把这条记录装到一个虚表当中,指针再指向下一条记录。如果为假那么指针直接指向下一条记录,而不进行其它操作。一直检索完整个表,并把检索出来的虚拟表返回给用户。EXISTS是条件表达式的一部分,它也有一个返回值(true或false)。在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,可以通过使用 EXISTS 条件句防止插入重复记录。

INSERT INTO TableIn (ANAME,ASEX) SELECT top 1 '张三', '男' FROM TableInWHERE not exists (select * from TableIn where TableIn.AID = 7)

EXISTS与IN的使用效率的问题,通常情况下采用exists要比in效率高,因为IN不走索引,但要看实际情况具体使用:
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

in、not in、exists和not exists的区别:

先谈谈in和exists的区别:
exists:存在,后面一般都是子查询,当子查询返回行数时,exists返回true。

select * from class where exists(select'x"form stu where stu.cid=class.cid
)

当in和exists在查询效率上比较时,in查询的效率快于exists的查询效率
exists(xxxxx)后面的子查询被称做相关子查询, 他是不返回列表的值的.
只是返回一个ture或false的结果(这也是为什么子查询里是select 'x'的原因 当然也可以select任何东西) 也就是它只在乎括号里的数据能不能查找出来,是否存在这样的记录。

其运行方式是先运行主查询一次 再去子查询里查询与其对应的结果 如果存在,返回ture则输出,反之返回false则不输出,再根据主查询中的每一行去子查询里去查询.

执行顺序如下:
1.首先执行一次外部查询
2.对于外部查询中的每一行分别执行一次子查询,而且每次执行子查询时都会引用外部查询中当前行的值。

3.使用子查询的结果来确定外部查询的结果集。
如果外部查询返回100行,SQL   就将执行101次查询,一次执行外部查询,然后为外部查询返回的每一行执行一次子查询。

in:包含

查询和所有女生年龄相同的男生

select * from stu where sex='男' and age in(select age from stu where sex='女')

in()后面的子查询 是返回结果集的,换句话说执行次序和exists()不一样.子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出.

not in和not exists的区别:
not in 只有当子查询中,select 关键字后的字段有not null约束或者有这种暗示时用not in,另外如果主查询中表大,子查询中的表小但是记录多,则应当使用not in,
例如:查询那些班级中没有学生的,

select * from class where cid not in(select distinct cid from stu)

当表中cid存在null值,not in 不对空值进行处理
解决:

select * from classwhere cid not in(select distinct cid from stu where cid is not null)

not in的执行顺序是:是在表中一条记录一条记录的查询(查询每条记录)符合要求的就返回结果集,不符合的就继续查询下一条记录,直到把表中的记录查询完。也就是说为了证明找不到,所以只能查询全部记录才能证明。并没有用到索引。
not exists:如果主查询表中记录少,子查询表中记录多,并有索引。
例如:查询那些班级中没有学生的,

select * from class2where not exists(select * from stu1 where stu1.cid =class2.cid)

not exists的执行顺序是:在表中查询,是根据索引查询的,如果存在就返回true,如果不存在就返回false,不会每条记录都去查询。
之所以要多用not exists,而不用not in,也就是not exists查询的效率远远高与not in查询的效率。

来源:https://www.cnblogs.com/qlqwjy/p/8598091.html

END

推荐一位有走心的coder,致力于打造一款高质量技术流学习社群,他专注于分享Java技术干货,包括面试攻略,开发技巧,架构设计,职场心得等。

添加好友,回复入群,即可加入社群

mysql if exists用法_MySQL中EXISTS的用法相关推荐

  1. mysql中去重的用法_mysql中去重 distinct 用法

    在使用MySQL时,有时需要查询出某个字段不重复的记录,这时可以使用mysql提供的distinct这个关键字来过滤重复的记录,但是实际中我们往往用distinct来返回不重复字段的条数(count( ...

  2. mysql range用法_MySQL中Explain的用法总结(详细)

    本篇文章给大家带来的内容是关于MySQL中Explain的用法总结(详细),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 执行计划(query Execution plan) 语法e ...

  3. mysql数据库 or的用法_MySQL中or语句用法示例

    1.mysql中or语法的使用,在mysql语法中or使用注意点. 项目遇到坑,遍历发放奖励数据查询错误!!! $sql = 'SELECT * FROM `vvt_spread_doubleegg_ ...

  4. mysql outer join的用法_MySQL中join的用法

    JOIN的含义就如英文单词"join"一样,连接两张表,大致分为内连接,外连接,右连接,左连接,自然连接.这里描述先甩出一张用烂了的图,然后插入测试数据. 笛卡尔积:CROSS J ...

  5. mysql unsigned 用法_mysql中unsigned的用法

    unsigned 既为非负数,用此类型可以增加数据长度!例如如果 tinyint最大是127,那 tinyint unsigned 最大 就可以到 127 * 2unsigned 属性只针对整型,而b ...

  6. mysql获取当月最后一天_mysql中获取本月第一天、本月最后一天、上月第一天、上月最后一天

    mysql获取当月最后一天_mysql中获取本月第一天.本月最后一天.上月第一天.上月最后一天等等 转自: https://blog.csdn.net/min996358312/article/det ...

  7. mysql的exists解析_mysql中关于exists的深入讲解

    mysql中关于exists的讲解 我认为exists语法是mysql中一个很强大的工具,可以简单地实现某些复杂的数据处理. 下面我谈谈与exists有关的三个方面. all 与 any 首先,看到了 ...

  8. mysql中正则表达式的用法_Mysql中正则表达式Regexp常见用法

    Mysql中Regexp常见用法 模糊匹配,包含特定字符串 # 查找content字段中包含"车友俱乐部"的记录 select * from club_content where ...

  9. php中使用mysql的视图_MYSQL中视图的用法介绍(代码示例)

    本篇文章给大家带来的内容是关于MYSQL中视图的用法介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.什么是视图 执行一条SQL,将结果集保存在一张虚拟表中 (相关 ...

最新文章

  1. SQL Server各种日期计算方法
  2. sftp工具都有哪些_色彩校正的工具都有哪些?
  3. Java生态系统– 2014年我的5大亮点
  4. 判断一个程序员水平高低的标准?
  5. LeetCode 1553. 吃掉 N 个橘子的最少天数(BFS)
  6. sqlmap --os-shell反制小思路
  7. hbuilder的aptana php插件无法提示命名空间之外函数和对象的解决办法
  8. 贝叶斯信念网络Bayes Belief network
  9. django如何连接mysql_Django如何连接mysql
  10. 怎样增加Dave 英语学习小组
  11. apt get 安装mysql5.7_ubuntu16.04下apt-get安装mysql5.7,文件目录结构
  12. 人工智能教程(1.1)
  13. error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools“: h
  14. java新手怎么用if alse_关于java:为什么“F”+“alse”不是==“False”?
  15. vlookup多条件的使用
  16. 博弈论+指鹿为马DP法(CSU 2095: Sweet War题解)
  17. Linux 系统中 resolv.conf 文件详解
  18. 中央处理器——硬连线控制器
  19. mmTrix大数据分析平台构建实录
  20. Python 根据两列/多列合并数据表

热门文章

  1. 任何项目都适用的CMakeLists配置
  2. C# partial 部分类使用简单举例说明
  3. java通过POI技术将HTML文件转成Word
  4. rdd.foreach(print)报错SyntaxError: invalid syntax
  5. gprs模块ftp 远程升级_基于GPRS无线通信技术的冷链监测系统
  6. python采用面向对象编程模式吗_如何理解 Python 中的面向对象编程?
  7. 电子科学与技术与计算机专业,计算机科学与技术专业和电子科学与技术专业,哪个好些?...
  8. kalilinux安装qt_Kali Linux 安装和搜狗输入法的安装
  9. MySQL 服务无法启动--服务没有报告任何错误 ---Failed to find valid data directory.
  10. 中关村win11 32位官方原版iso文件v2021.08