T-SQL查询阶段详解――T-SQL读书笔记(一)

2014-11-24 15:31:13 · 作者: · 浏览: 2

T-SQL查询阶段详解——T-SQL 读书笔记
一、sql语言执行顺序
(8) SELECT (9) DISTINCT (11)
(1) FROM
(3) JOIN
(2) ON
(4) WHERE
(5) GROUP BY
(6) WITH {CUBE | ROLLUP}
(7) HAVING
(10) ORDER BY
www.2cto.com
简介: 1、从FROM处开始执行:对语句中的前两个表执行笛卡尔乘积,生成虚拟表VT1。
2、ON:对VT1运用筛选器,使符合条件为真的行插入VT2
3、Outer(JOIN):如果指定了CROSS JOIN或者 INNER JOIN 中未找到匹配的行将作为外部行添加到VT2中,生成VT3。如果存在多个表连接则会重复执行1—3。
4、Where:对VT3使用where_cntion 作为筛选器,为true的行插入VT4
5、Group by:对VT4中的行按列分组 ,生成VT5
6、CUBE/ROLL UP:把超组插入VT5生成VT6
7、HAVING:对VT6应用Having_condition筛选器,为true的插入VT7
8、Select:处理select子句中需要的列,筛选出VT8
9、Distinct:去除VT8中的重复行,产生VT9
10、Order By:将VT9中的行按顺序排列,并生成一个游标(VC10)
11、从VC10中选择指定数量的或比例生成表VT11,返回给调用者。
二、各步骤执行顺序详解及注意事项
1、生成迪卡尔乘积,迪卡尔乘积表的大小为 表1.M行*表2.N行,如果查询表超过四个VT1数据容量的将相当大,应尽量控制在3个以内。其次如果表中有列名重复的需要为其指定表名 www.2cto.com
在此后的执行中都需要指定其源表名。
2、应用ON筛选器在VT1中。
注意:sql中的三值逻辑,true、false、unknown,对unknown的处理。
在ON、having、where筛选器中都认为unknown为false
在check、unique约束中认为是true
在order by、group by会把unknown的值分、排列在一起。
3、添加外部行:这步是针对有外部连接的时候会有,因为在指定连接的时候(lfet、right、full)join时会把一张表或者两张表作为保留表,表示你希望返回保留表中所有的行。步骤3返回
步骤2中的行,并添加保留中在2中被过滤掉的行。
4、应用where筛选器,对上一步返回的所有行应用Where筛选条件。
注意:对包含Outter join子句的查询即逻辑表达式应该在on中应用还是在Where中使用了,需要考虑到on是在添加外部行之前过滤行,但是步骤三会把这些过滤掉的行又添加回来而where则
是在添加完外部行后对所有的行进行筛选。Where的筛选才是最终的。
5、Group by 在这个步骤中,把上一步返回的行被分配到各个分组中。子句中的每一个列的唯一值被分为一组,上一步返回的每个行被分配到一个组。生成的虚拟表vt5,VT5的表结构如下: www.2cto.com
Group section(分组列)+Raw Section(分组行)。
注意:1、所有后续步骤只能指定可以成组得到的标量表达式。及只能是分组列,及使用聚合函数的表达式。
2、Gorup by all coulumn 会把Where筛选器过滤掉的行又重新添加到VT5表中。
3、标量表达式指计算结果是一个特定数据类型的标量值。
6、应用Cube或ROLL UP创建超组并添加到上一步返回的虚拟表VT6中。
注意:1、cube 是针对步骤5中的所有分组列按排列组合的方式进行分组统计,例如:分组列 A、B、C 使用cube后产生的结果集是针对按A、AB、ABC、B、BC、C分组统计后放入结果集中。
2、ROLL UP是CUBE的一个特列,它的使用场景是针对层次结构的一种分组统计。 例如:分组列:Year、Month、Day 使用ROLL UP后的结果集是对A、AB、ABC分组统计后和并的结果集
3、使用CUBE是需要注意,如果分组列的源表中本来就包含null时需要将null替换成其它的值,因为一旦使用cube或Roll UP其结果集中会产生null值(其意义表示全部) www.2cto.com
7、Having筛选VT6中,对已分组的数据进行筛选生成VT7。
注意:1、子查询是不能作为Having的筛选条件
2、Count(*)或Count(column)的区别在于,Count(*)会把外部行也统计在内,使得无法准确的数据。
8、Select选出需要的列,构建一张最终被调用的表VT8.
注意:1、Select表达式返回虚拟表中的基列,如果查询的是聚合查询那么只能是成组部分的基列或通过聚合运算后的原始列。
2、在次步骤中指定的列、表别名可以在后续步骤中得到使用。
3、同时操作,
9、应用Distinct子句对VT8中产生的重复行进行剔除,但是在运用了GROUP by后使用Distinct是多余的步骤。 www.2cto.com
10、对VT9按Order By子句中的列进行排序,返回游标VC10。
注意:1、游标是包含特定物理顺序组织的行。sql是针对集合的查询,集合是没有顺序可言的。
2、如果指定了Distinct不能访问未返回的表达式,及只能访问在select中指定的列但是如果没有指定Distinct的话可以访问Select之前的VT7和VT8中的列,允许使用select中没有的列进行排序。
3、表达式包括:视图、内联表值函数、cte公用表达式、子查询、派生表但是使用了Order by后返回的是游标而不是表达式。
11、TOP 从游标上返回指定的行数生成VT11返回给调用者。
注意:1、如果未指定Order by子句而使用TOP语句,每次查询可能会返回不同顺序的结果集,因为返回的行可能是物理上最先访问到的。
2、Select *