案例2: 理解EXISTS与NOT EXISTS 子查询的执行机制。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
提问:为什么这样写就可以得到A,B,C分组后每组里除了最小记录的其它记录~这个子查询到底起了个什么作用。能不能大概模防一下他执行的过程或是原理什么的~我也知道上这个语句如果换成
select distinct * from tb a where not exists(select 1 from tb where F1=a.F1 and id<a.id)
就可以得到分组后每组的最小值,或是把“<”换成“>”号可以得到最大值,但就是想不出来为什么会得到这个值~这样去理解就知道为什么了:
回答:扫描了tb(外表)的记录,并将每记录对应去判断(内表)exists的查询是否会返回一个结果集
如果会, 则这条记录保留, 否则这条记录不保留,exists中的a.f1, a.id 的值来源于当前被扫描到的记录.
这是一个嵌套循环的过程。(可点击T-SQL编辑器中的“显示估计的执行计划")来看执行过程。
再分析何时该使用IN,何时使用EXISTS:IN与EXISTS对比区别,in 是把外表和内表作hash join,而exists是对外表作loop,每次loop再对内表进行查询。结论:这样的话,
对两个不同表作相关子查询时,in适合内外表都很大的情况,exists适合外表结果集很小的情况。
对同一个表作相关子查询时,使用exists性能高些。