exists sql用法_sql中级进阶(一) exists的用法

351241b92d27250a7c7870fb79cb4cb2.png

写这个也不是为了给什么人看,就当是自己工作的一些总结吧.

exists,工作中应该看个人写法,但是涉及后续进阶,哪怕自己不写,至少能看懂别人的代码,而且exists有时候效率会高于in,粗略写写,实际我不大用......

0bfc5452600f54dee1ec0ffd8638202e.png
a1表

084f4d94b86b9737b19038303abf72a2.png
b1表

(1)原理

执行顺序如下:

1.首先执行一次外部查询

2.对于外部查询中的每一行分别执行一次子查询,而且每次执行子查询时都会引用外部查询中当前行的值。

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

如果内层子查询有行返回,则返回ture,进行外层当前行语句的执行.

如果内层子查询无行返回,则返回flase,进行外层当前行语句的执行,当然不会执行,返回为空

一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。

以下粘贴,留作备注. 确实涉及到了指针,数据库的指针应该就是游标,大概就是iterator把......

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

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

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

(1)第一种情况

select * from  a1
where EXISTS (select 1 from  b1 where a1.aid = b1.aid)

1a3ddf6412500ce2225bfc51069bdc10.png
1

首先执行外层语句

1.即select * from a1,之后外层的每一行都会对内层语句做一次子查询.也可以说是循环.

2从表a1中第一条数据1 a1开始,进入exsits函数,当前子查询where中,有没有b1.aid=1的数据?因为存在,则返回ture. 这个1也就是外查询的第一条数据的a1.aid.

3.之后外查询第二行,子查询存在满足条件的值所以都返回.

4.第三行,此时a1.aid=3 子查询里面变成 where b1.aid=3 不存在此值,返回flase,所以没有第三个记录

5.补充一下,比如查询第二行的时候.(select 1 from b1 where a1.aid = b1.aid) 即子查询中应该也是一个循环,,外面的a1.aid=2 此时子查询运行到b1的第一行,即b1.aid=1,flase不满足,之后运行到子查询b1的第二行 b1.aid=2 ture满足外面的a1.aid=2 true返回.结束里层循环.

其实里面的循环也是进行一次又一次判断,返回ture就直接结束,flase继续执行里面的下一条数据.大概类似于双层for循环把.

(2)第二种情况

select * from  a1
where EXISTS (select 1 from  b1 where a1.aid = 1)

a90976091d344888b27b65fb2e4e0400.png

1.主查询执行

2.a1第一行数据 此时 a1.aid=1 与子查询里面的数据呼应 ture 返回

3.第二行,此时a1.aid=2 子查询不满足 flase

4.第三行,同上

(3)第三种情况

select * from  a1
where EXISTS (select 1 from  b1 where b1.aid = 1)

ca1a5679f4366d27c0935a84007efff5.png

1.主查询执行

2.a1第一行数据 此时子查询存在b1.aid=1的数据 ture返回

3.第二行,此时子查询再次来到子查询b1表中的第一行,满足b1.aid=1返回

4.第三行,同上

(4)效率问题

这个还是理解记比较好记

where是先执行子查询where子句,再执行主句 所以在主表大 而子查询中表小时候,效率高

exsits相反, 主表小,而子查询表大时候,效率高

结束,就这样总结吧,实际用的也不多........

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值