select 语句的执行顺序
借用ItZik Ben-Gan、Lubor Kollar、Dejan Sarka所著的《Sql Server 2005 技术内幕:T-SQL查询》的一段话足以说明:
(8) select (9) distinct (11) <top_specification > <select_list>
(1)from<lef t_table>
(3) <join_type> join <right_table>
(2) on <join _condition>
(4) where <where_condition>
(5)group by <group_by_list>
(6) with {cube|rollup}
(7)having(having_condition)
(10) order by <order_by_condition>
从这个顺序可以看出,所有的查询语句都是从from开始执行的。在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的基础。
第一步:from
首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表vt1 .
第二步:on
接下来便是应用on筛选器,on 中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 vt2 .
第三步:join
如果是outer join 那么这一步就将添加外部行,left outer jion 就把左表在第二步中过滤的添加进来,如果是right outer join 那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表 vt3.
第四步:多表
如果 from 子句中的表数目多余两个表,那么就将vt3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 vt3.
第五步:where
应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表vt4,在这有个比较重要的细节不得不说一下,对于包含outer join子句的查询,就有一个让人感到困惑的问题,到底在on筛选器还是用where筛选器指定逻辑表达式呢?on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步outer join中还可以把移除的行再次添加回来,而where的移除的最终的。
第六步:group by
分组,生成虚拟表 vt4
第七步:having
对vt4应用having筛选器,生成虚拟表 vt5
第八步:select
处理select 列表,生成虚拟表vt6
第九步:distinct
将vt6 中重复的行去掉,生成虚拟表vt7
第十步:order by
将vt7中的行按order by 子句中的列列表排序,生成一个游标vc8
第十一步:top
从vc8的开始处选择指定数量或比例的行,生成虚拟表vt9,并返回给调用者