参考文献《Ms SQl server技术内幕 T-SQL查询》
作为一个SQL Server的初学者,了解SQL各个查询的步骤十分重要,如果连SQL的基本执行顺序都不知道,那么会很容易写出不恰当甚至错误的查询。比如,如果你不了解使用外连接时Where筛选器与On筛选器的使用规则,比如,如果你不知道Top运算符的与Order by子句的一些使用规则,都有可能让你得到意想不到的结果。
在SQL Server中,逻辑查询主要有一下几个步骤:
1、From子句,返回行结果集VT1。其中From子句又可分为三个阶段:1-J1、基本表之间作笛卡尔积;1-J2:使用On筛选器筛选出符合规则的行集;1-J3:如果是外部查询,添加外部行;
2、Where子句,返回行结果集VT2。使用Where子句对阶段1查询返回的结果行集VT1进行筛选,所有Where后面的值为True的行被插入到虚拟表VT2中;比如,使用了Where Age > 18,则,只有年龄(Age)大于18岁的行才会被筛选插入到VT2;
3、Group子句,返回行结果集VT3。按照指定的列中对虚拟表VT2进行分组,并最终生成结果集VT3,。比如,使用了Group By [Class](班级),则所有班级相同的学生被分到同一组。最终所有的组(可能有许多组,比如计科10101班,计科10102班……)组合成结果集VT3;
4、Having子句,返回行结果集VT4。Having是针对Group By子句中每一组进行筛选而使用的。比如使用子句Having Count(*) > 5,则只有组中行数大于5行的组才会被筛选出来并插入到虚拟表VT4。如以上例子,假定计科10101班该组只有4行,则该组不会被返回;
5、Select子句,返回行结果集VT5。Select子句也可分为三个阶段:5-J1,计算Select列表达式的值;5-J2,如果使用了Distinct关键字,则去除相同行;5-J3,如果使用了Top关键字,则根据Top定义的逻辑顺序,选择指定数量的行返回;
6、Order By子句,返回游标结果VC6。根据Order by指定列,对VT5返回的结果集进行排序,并返回游标结果VC6;
需要注意的几个点:
一、Where筛选与On筛选器的差异:当使用外连接如Out Left Join时,你可能会在考虑是在On中指定筛选条件,或者是在Where子句中指定条件。那这两者有何区别呢?Where筛选器对行的筛选是最终的,也就是某行一旦被淘汰,则该不会再出现在结果集中;而On筛选器对行的筛选并不是最终的,因为使用On筛选器淘汰的行可能在添加外部行时再次添加回来。
例,使用表结构、数据如下:
比如说,考虑如下查询:返回来自”常德“还没有安排班级的学生(班级的属性值为null),如果在On筛选其中对城市列进行筛选结果如下图:
显然,结果是错误的,因为在On筛选器筛选了行在添加外部行时再次添加了进来。
此时,返回结果显然是正确的。
另外:只有在使用外连接时才有会Where以及On的这种区别,在内连接时因为没添加外部行的步骤,所以在哪儿指定都是一样的。