标题:第1章 逻辑查询处理 笔记
作者:王运亮(wwwwgou)
时间:2011-04-11
地点:陕西西安
说明:本章内容为T-SQL基础中的基础。
博客:http://blog.csdn.net/wwwwgou
--==============================================
--SQL逻辑执行顺序
(8) SELECT (9) DISTINCT (11) <TOP_specification> <select_list>
(1) FROM <left_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_list>
--SQL逻辑执行顺序注释
(1) 执行笛卡尔乘积.如果有多个表JOIN, 则执行顺序可以理解成: 先执行INNER JOIN, 其它按出现的顺序JOIN.
(2) 应用ON筛选器.注意把过滤条件放在ON和放在WHERE中的区别: INNER JOIN无区别, OUTER JOIN有区别.
还要注意三值逻辑:在筛选器中UNKNOW=FALSE, 在CHECK中UNKNOW=TRUE,UNIQUE约束, 排序操作和分组操作认为两个NULL是相等的.
(3) 添加外部行.外部联接包含: LEFT,RIGHT,FULL.
(4) 应用WHERE筛选器.注意把过滤条件放在ON和放在WHERE中的区别:ON在添加外部行(步骤3)之前被应用, 而WHERE是在步骤3之后应用.
(5) 分组.2000不允许的写法(2005可以): SELECT NextYear = YEAR(orderdate)+1 FROM table_name GROUP BY YEAR(orderdate).
如果用GROUP BY ALL(非标准遗留物), 则相当于跳过(4)WHERE过滤, 在用INNER JOIN时结果会和GROUP BY不同
(6) 应用CUBE或ROLLUP.注意GROUPING函数在这里的应用.
(7) 应用HAVING筛选器.注意COUNT(*)和COUNT(field_name)的区别.子查询不能被用作聚合函数的输入: HAVING SUM((SELECT ...)) >10.
(8) 处理SELECT列表.注意SQL的同时操作特性.
(9) 应用DISTINCT子句.DISTINCT应该在TOP之前.
(10)应用ORDER BY子句.唯一一个可利用SELECT列列表中的别名的地方.如果有DISTINCT关键字, ORDER BY中只能出现SELECT列列表中的列.
SQL是基于集合理论的.ORDER BY中可以使用数字代表列, 但不推荐.
因为ORDER BY只返回游标, 所以结果不能用作表表达式(视图, 内联表值函数, 子查询, 派生表, CTE), 但带TOP的选项除外.
(11)应用TOP选项.可以使用WITH TIES.2000只能是整数, 2005可以是表达式.
如果不指定ORDER BY, 查询结果将是不确定的, 返回的行是SQL Server物理上最先访问到的行.使用TOP后将返回一个结果集, 而并非游标.
--用于FROM子句的表运算符(JOIN, APPLY, PIVOT, UNPIVOT)
(J) <left_table_expression>
<join_type> JOIN <right_table_expression>
ON <join_condition>
1. J1: 交叉联接左输入和右输入
2. J2: 应用ON子句
3. J3: 添加外部行(INNER JOIN没有此步骤)
(A) <left_table_expression>
{CROSS | OUTER} APPLY <right_table_expression>
1. A1: 把右表表达式应用到左表输入的行.理解: 先计算左输入, 然后为左输入的每一行计算一次右输入.
2. A2: 添加外部行(CROSS APPLY没有此步骤)
(P) <left_table_expression>
PIVOT (<aggregate_func(<expression>)> FOR
<source_col> IN(<target_col_list>))n
AS <result_table_alias>
1. P1: 隐式分组.理解: 除了FOR和IN后的2个字段, 按剩下的字段隐式分组.
2. P2: 隔离值.理解: 生成CASE WHEN <source_col> = <target_col_element> THEN <expression> ELSE NULL END.
3. P3: 应用聚合函数.理解: 把聚合函数应用在CASE WHEN最外层: aggregate_func(CASE WHEN ... END)
(U) <left_table_expression>
UNPIVOT (<target_values_col> FOR
<target_names_col> IN(<source_col_list>))
AS <result_table_alias>
1. U1: 生成副本
2. U2: 隔离目标列值 --前2步可以用UNION ALL来理解.
3. U3: 过滤掉带有NULL的行 --注意: 字段值为NULL的行将被过滤掉
--新的OVER子句
1. 相当于GROUP BY
2. 只有2个阶段可以使用OVER: SELECT (8)和ORDER BY(10)
3. 先用WHERE过滤得到一个结果集, 再在这个结果集的基础上用OVER(相当于一个GROUP BY子查询)计算的值对应到每一行.
--新的集合操作(EXCEPT INTERSECT, UNION [ALL])
1. EXCEPT A和B的差(A-B), 并且会排除重复值
2. INTERSECT A和B的并(A交B), 并且会排除重复值
3. UNION A和B的和集, 并且排除重复值, UNION ALL不会排除重复值
4. 可以在最后加上ORDER BY, 原理是在所有的集合操作完成后, 再ORDER BY
5. NULL在对比时认为是相等的