第1章 逻辑查询处理

--==============================================

标题:第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在对比时认为是相等的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值