张晶晶的空间

我们一直在努力....

sql多表查询之四:子查询EXISTS

标签: sql多表查询 子查询EXISTS

大家都领会过使用sql多表查询之三:子查询IN的奇妙了吧,还看到有朋友提到子查询的效率问题,很高兴大家能重视效率。那今天我们将介绍sql多表查询系列的最后一菜,压轴菜——sql多表查询之四:子查询EXISTS。
什么是子查询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'
这时,两个条件要判断的值都已经知道

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

好了,sql多表查询之四:子查询EXISTS就介绍到这里了,如何用子查询EXISTS来改造我们上期说的查询前三名的学生成绩呢,就留给大家去实践啦
在本文的开篇,我们提到过子查询EXISTS” 子查询实际上不产生任何数据”,看上去他比IN的效率要高很多呢,绝对是这样吗?当然不?否则IN早就被子查询EXISTS取代了嘛
那该如何判断要用子查询IN还是子查询EXISTS呢,当然要具体情况具体分析(汗!有人该说这不是废话了嘛)
哈哈,大家可以掌握一个小原则:
如果外表的记录很多而子查询的记录相对较少的话,建议采用子查询IN写法;相反,如果子查询的记录很多而外表的记录相对较少,则建议采用子查询EXISTS写法。
其它情况???就只能还是那句:具体情况具体分析:D
其实子查询IN是一定可以用EXISTS写出来的,但有些是必须要用子查询EXISTS,无法用IN写出来的
所以,关于子查询IN 与子查询EXISTS的PK,大概还是子查询EXISTS要稍胜一筹啦!
好了,关于SQL多表查询四个部分就介绍到这里啦,谢谢大家的支持!!
下次我们来介绍介绍SQL2008的新东东,和数据仓库的一些好东东,希望大家多多关注xj的博客~~~~~~~


    分享: 收藏到CSDN 收藏到javaeye 收藏到博客园 收藏&分享
  • 浏览 (1589)
  • 评论 (0)
  • 发表于 2009-08-20 09:45
  • ERP世界
    评分: 请先登录再投票,同一篇博客一月只能投票一次!
    无人投票

相关博客:


评论


发表评论

关注此文的人们还关注