子查询之 exists 和 in

exists

exists用于检查一个子查询是否至少会返回一行数据(即检测行的存在),返回值为boolean型,true或false

语法

exists subquery
/*
参数: 
subquery是一个受限的select语句(不允许有compute子句和into关键字),该语句返回一个结果集。
返回结果类型:boolean类型
如果子查询包含行,则返回true,否则返回false,即言:exists根据subquery的结果集是否为空来返回一个布尔值——如果不为空则返回true,否则返回false
*/

​ table1 table2

​ id class_name id name class_id

​ 01 一年级 01 张三 01

​ 02 二年级 02 李四 02

​ 03 三年级 04 王五 04


-- 1、在子查询中使用NULL仍然返回结果集:
select * from table1 where exists(select null)
-- 该条sql语句等同于:
select * from table1

​ 其查询结果为:

​ id class_name

​ 01 一年级

​ 02 二年级

​ 03 三年级


-- 2、
select t1.id,t1.class_name from table1 t1 where exists (select * from table2 t2 where t2.class_id = t1.id)
-- 该条sql语句等同于:
select t1.id,t1.class_name from table1 t1 where t1.id in (select t2.class_id from table2 t2 where t2.class_id = t1.id)

其查询的结果为:

id class_name

01 一年级

02 二年级

select t1.id,t1.class_name from table1 t1 where exists (select * from table2 t2 where t2.class_id = '01')
-- 等价于select * from table2 t2 where t2.class_id = '01'有数据存在,所以exists返回true;

select t1.id,t1.class_name from table1 t1 where exists (select * from table2 t2 where t2.class_id = '02')
-- 等价于 select * from table2 t2 where t2.class_id = '02'有数据存在,所以exists返回true;

select t1.id,t1.class_name from table1 t1 where exists (select * from table2 t2 where t2.class_id = '03')
-- 等价于 select * from table2 t2 where t2.class_id = '03'没有数据存在,所以exists返回false;

执行过程理解:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,即exists子句返回true,则外查询的这一行可作为外查询的结果行,否则不能作为结果。

  • 分析器会先看语句的第一个词,当它发现第一个词是select关键字的时候,它会跳到from关键字,然后通过from关键字找到表名并把表装入内存,接着是找where关键字,如果找不到则返回到select找字段解析,如果找到where,则分析其中的条件,完成后再回到select分析字段,最后形成一张*虚表*
  • where关键字后面的是条件表达式,条件表达式计算完成后,会有一个返回值,即非0或0,非0即为真(true),0即为假(false)。如果为真则执行select语句,否则不执行select语句。
  • 分析器先找到关键字select,然后跳到from关键字,将该关键字后面的表导入内存,并通过指针找到第一条记录,接着找到where关键字计算它的条件表达式,如果为真那么把这条记录装到一个虚表当中,指针再指向下一条记录。如果为假那么指针直接指向下一条记录,而不进行其它操作。一直检索完整个表,并把检索出来的虚拟表返回给用户。exists是条件表达式的一部分,它也有一个返回值(true或false)。
-- 在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,可以通过使用EXISTS条件句防止插入重复记录。
   insert into table1 (id,class_name) values ('03','四年级') where not exists (select * from table1 where table1 = '03')

in(待更新)

exists 与 in 的区别

1、in引导的子句只能返回一个字段,exists子句可以有多个字段;

2、通常情况下采用exists要比in效率高,因为in不走索引,但要但要具体情况具体分析:in适合于外表大而内表小的情况;exists适合于外表小而内表大的情况。

参考文档

posted @ 2020-11-13 14:28  至安  阅读(834)  评论(0编辑  收藏  举报