是什么?

这个问题其实很好理解,简单来说,EXISTS 就是mysql中的一个关键字。

能干啥?

Exists关键字的主要作用就是检查SQL语句中的子查询是否至少会返回一行数据。使用EXISTS 关键字的子查询 其实并不返回数据,而是返回 布尔类型的true或 false。

怎么用?

那么EXISTS 关键字到底该怎么用呢,我们通过例子来进行简单讲解。所有的例子都基于MySQL 5.7版本。

EXISTS 语法

根据Mysql5.7版本的开发手册,其语法格式如下:

SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2);

理论上来说,Exists 关键字后边的subquery(子查询,又名“相关子查询”) 可以以 SELECT * 或者 其他 任意字段 开头,比如你可以 使用:

SELECT * FROM t1 WHERE EXISTS (SELECT 'A' FROM t2);

或者

SELECT * FROM t1 WHERE EXISTS (SELECT '法外狂徒张三' FROM t2);

等等任何你想使用的字段查询,这都是可以的,因为 MySQL 会忽略掉Exists 关键字 后边subquery中的字段列表,因此在这个地方你使用任何字段都是可以的。但是在我们实际工作中,习惯使用
SELECT 1 来代替,如下所示:

SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2);

EXISTS 执行顺序

我们以以下SQL语句为例:

SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.id = t2.id);

顺序如下:

  1. 首先执行外部查询,并缓存结果集:
SELECT * FROM  t1;
  1. 遍历外部查询结果集的每一行Record(记录),然后代入子查询中作为条件进行查询。
SELECT 1 FROM t2 WHERE t1.id = t2.id;
  1. 如果子查询有返回结果,则EXISTS子句返回true,则外部查询的这一行记录可作为结果行返回,否则不能作为结果。

SQL语句示例

为了便于演示,我们创建两张表结构非常简单的表,班级表(class)和 学生表(student)
class表结构:

CREATE TABLE `class` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(100) DEFAULT NULL comment '班级名称',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4-- 创建数据
INSERT INTO class(id, name)VALUES(1, '一年级');
INSERT INTO class(id, name)VALUES(2, '二年级');
INSERT INTO class(id, name)VALUES(3, '三年级');
INSERT INTO class(id, name)VALUES(4, '四年级');

student表结构:

CREATE TABLE `student` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`class_id` bigint(20) NOT NULL comment '班级表id',`name` varchar(100) DEFAULT NULL comment '学生名称',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4-- 创建数据
INSERT INTO student (id, class_id, name) VALUES(1, 2, '张三');
INSERT INTO student (id, class_id, name) VALUES(2, 2, '李四');
INSERT INTO student (id, class_id, name) VALUES(3, 1, '王五');
INSERT INTO student (id, class_id, name) VALUES(4, 1, '赵六');
INSERT INTO student (id, class_id, name) VALUES(5, 1, '王七');
INSERT INTO student (id, class_id, name) VALUES(6, 3, '赵八');
INSERT INTO student (id, class_id, name) VALUES(7, 4, '周久');
INSERT INTO student (id, class_id, name) VALUES(8, NULL, '小二');
  • 查询出一年级所有的学生
select * from student where exists (select 1 from class  where  class_id = 1);
  • 查询出不是一年级的所有学生
select * from student where not exists (select 1 from class  where  class_id = 1);
  • 查询出未分配班级的学生
select * from student s where exists (select 1 from class c where s.class_id is null );
  • 查询出 学生主键id 等于 班级主键id的学生
select s.* from student s where exists (select 1 from class c where s.id = c.id);

因为表结构相对简单,无法构造较负责的查询逻辑。在项目中根据业务逻辑灵活使用即可。

EXISTS 和 IN 查询原理比较

其实能使用exists查询的语句基本上都能使用 IN 实现,但是两者还是一些区别的。

  • EXISTS : 外表先进行查询,然后循环查询结果,将查询结果放入exists的子查询中进行条件验证,true 则保留,false则丢弃。

  • IN : 先查询内表,将内表的查询结果当做条件提供给外表查询语句进行比较。

由上可以得出结论:

  1. 外层小表,内层大表(左小表,右大表): exists 比 in 的效率高。
  2. 外层大表,内层小表(左大表,右小表): in 比 exists 的效率高。

MySQL EXISTS 关键字使用相关推荐

  1. MySQL函数关键字(五)子查询 ANY/SOME/ALL/IN/EXISTS/USING

    MySQL 官方手册 8.0 Reference Manual - Subqueries with ANY, IN, or SOME 1. ANY与ALL对比 operand comparison_o ...

  2. MySQL带EXISTS关键字的子查询

    EXISTS关键字 后面的参数,可以是任意一个子查询,这个子查询的作用相当于测试,它不产生任何数据,只返回TRUE或FALSE 当返回值为TRUE时,外层的查询才会执行 查询employee表中,是否 ...

  3. MySQL保留关键字

    今天在使用hibernate关联映射导出表的时候因为映射了一个表名为option,是MYSQL的关键字,总是生成错误,一开始以为是映射文件和代码问题,检查不出问题才想到可能用到数据库的保留关键字了,查 ...

  4. Mysql Exists与in_在MySQL里,有个和in一样的东东叫做exists,但是它比in更牛叉,你会么?...

    我们在学习Yii2的时候,一定接触过这样的where输入 $query->where(["exists",xxxx]); User::find()->where([&q ...

  5. [转载]MySQL exists的用法介绍

    原文摘自:http://www.cnblogs.com/glory-jzx/archive/2012/07/19/2599215.html MySQL exists的用法介绍 有一个查询如下: 1 S ...

  6. mysql常见关键字的用法_MySQL 常用关键字用法详解

    MySQL 常用关键字用法详解 在开发工程中,操作数据库的时候经常会有不同类型的条件查询,除了使用where外,Mysql本身也提供了很多常用的关键字.本文主要介绍一些常用的关键字,像update.i ...

  7. mysql exists怎么用_Mysql exists用法小结

    简介 EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False. EXISTS 指定一个子查询,检测行的存在.语法:EXISTS subquer ...

  8. mysql exists依赖查询_MySQL EXISTS 和 NOT EXISTS 子查询

    MySQL EXISTS 和 NOT EXISTS 子查询语法如下: 1 SELECT ... FROM table WHERE EXISTS (subquery) 该语法可以理解为:将主查询的数据, ...

  9. mysql status关键字 数据表设计中慎重使用

    mysql status关键字  数据表设计中慎重使用 转载于:https://www.cnblogs.com/toSeeMyDream/p/5574894.html

最新文章

  1. Android获取相册中图片的路径 4.4版本前后的变化
  2. 模型训练 准确率下降_手写批量线性回归算法:在Python3中梯度下降方法实现模型训练
  3. 成功解决SQL Server软件中出现的18456问题
  4. buu RSAroll
  5. 第一次小班课(英语)
  6. 随机存取存储器(RAM)
  7. IP协议包中的TTL(Time-To-Live)
  8. python loggeru模块_python常用模块——logger模块
  9. oracle 用户解锁和修改用户密码
  10. 支付接口调用成功后如何让前端知道_开发口中的「接口」到底是什么
  11. 技术人员日本游学之精益管理
  12. 阜南一中2021高考成绩查询,高考喜报出炉!阜南一中、阜阳一中、三中……取得了怎样的好成绩?(附名单)...
  13. 有关bug走过的坑(复盘总结)
  14. 转:将HTML5封装成android应用APK文件的几种方法
  15. 计算机上自带的打字游戏,在学校上电脑课打字游戏的日子
  16. NLPIR-ICTCLA2018分词用户大会线上抢票报名开始
  17. 桑基图可视化图表使用技巧全解析
  18. 系统安装,UltraISO制作U盘系统安装盘
  19. dropout法中为什么要除以keep_prob?
  20. input 输入数字而且最大为10

热门文章

  1. 看计算机组成原理,计算机组成原理
  2. 算法练习——在有序序列(r1,r2,...,rn)中,存在序号i(1<=i<=n),使得ri=i。请设计一个分治算法找到这个元素。 要求算法在最坏情况下的时间性能为O(logn))
  3. docker cuda的devel和runtime包
  4. 第十三届蓝桥杯模拟赛(第一期)题解
  5. android向DDR读写数据,透过数据看本质 -  被“吹爆”的LPDDR5内存究竟有多强大?...
  6. Windows下Armadillo配置及测试
  7. c#图片base64去转义字符_c#中图片与base64互相转换
  8. Preface---ITE EC
  9. 用户喜欢什么样的内容?
  10. jzoj4210. 我才不是萝莉控呢(B组——Day4)