sql查询EXISTS的用法

http://www.cnblogs.com/posoft/articles/1550453.html

上次介绍过sql 不等连接和sql子查询IN的用法,还看到有朋友提到子查询的效率问题,很高兴大家能重视效率。那今天我们将介绍子查询EXISTS的用法。
什么是sql子查询EXISTS?
子查询EXISTS是用来指定一个子查询,检测行的存在使用子查询EXISTS 关键字引入一个子查询时,就相当于进行一次存在测试。外部查询的WHERE 子句测试子查询返回的行是否存在。子查询实际上不产生任何数据;它只返回 TRUE 或 FALSE 值。要注意:在子查询中使用仍然返回结果集,通过使用EXISTS仍取值为 TRUE
通过对子查询 EXISTS的解释,大家可以发现子查询IN与子查询EXISTS的区别了吗?注意,EXISTS子查询实际上不产生任何数据;它只返回 TRUE 或 FALSE 值。
这样就不存在我们之前说“子查询IN适合外结果集大,子查询结果集小的情况。
好了,在我们了解EXISTS之前,让我们先来了解一下集合运算。
有两张表A和B

我们如何得到两表的 并、减、交、乘、除呢

首先来看 集合运算-并

这个SQL很简单啦

select * from #a
union all
select * from #b
 

 


再看 集合运算-减
减是要什么样的结果呢?
以下两个结果分别是A-B和B-A得出来的

SQL如何处理呢?轮到我们的子查询EXISTS上场了

select * from a t1
where not exists(
select 1 from b t2
where t1.key1=t2.key1 and t1.key2=t2.key2
)
 



再看 集合运算-交

结果是:

SQL与减的很类似:

select * from #a t1
where exists(
select 1 from #b t2
where t1.key1=t2.key1 and t1.key2=t2.key2
)
 


看出他们的区别了吗?

集合运算-乘

结果集

其实这个我们的日常工作中使用的最多了,就是连接啦

SQL很简单:

select * from #a,#b
 


最后,我们来看 集合运算-除

可能有些朋友对除出来的结果还有些陌生呢
结果集相除,会是什么结果呢?
不是任何表相除都是有结果的
这时,上面的两张表我们是用不上了,我们得来看下面这两张表,相除的条件

朋友们,看出他们是怎么除出来的吗?

SQL怎么写呢,想想,再看结果:

select a,b from #1 bb
where exists(
select 1 from (
select distinct #1.a,#1.b,#2.a c,#2.b d from #1,#2
) aa
where aa.a=bb.a and aa.b=bb.b and aa.c=bb.c and aa.d=bb.d
) group by a,b having count(*)>1
 



再来看一个吧:



SQL呢?

select distinct a,b from #1 a
where not exists(
select * from #2 b where not exists(
select * from #1 where a=a.a and b=a.b and c=b.a and d=b.b
)
)
 


如何理解呢
逐条扫描#1中的每条记录.
扫描每一条的时候,假设 a=‘a’ and b=‘b’
开始去判断条件,即执行:

select * from #2 b where not exists(
select * from #1 where a='a' and b='b' and c=b.a and d=b.b
)
 


这时,又是一个子查询, 它又逐条扫描#2的每条记录.
扫描每一条的时候,假设c=‘c’ and d=‘d’,然后开始去判断条件
即执行:

select * from #1 where a='a' and b='b' and c='c' and d='d'
 


这时,两个条件要判断的值都已经知道

查询就可以得到结果,看是否存在记录.然后将结果返回外层查询.

那么该如何判断要用子查询IN还是子查询EXISTS呢,当然要具体情况具体分析(汗!有人该说这不是废话了嘛)
哈哈,大家可以掌握一个小原则:
如果外表的记录很多而子查询的记录相对较少的话,建议采用子查询 IN写法;相反,如果子查询的记录很多而外表的记录相对较少,则建议采用子查询EXISTS写法。
其它情况???就只能还是那句:具体情况具体分析:D
其实子查询IN是一定可以用EXISTS写出来的,但有些是必须要用子查询EXISTS,无法用IN写出来的
所以,关于子查询IN 与子查询EXISTS的PK,大概还是子查询EXISTS要稍胜一筹啦!

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值