Microsoft Sql Server 2008技术内幕:T-SQL 查询【第一章 逻辑查询处理(20150622)】

注:本文是自己学习摘要,以便后面查询,无其他目的!

 

 

logical query processing

 前言

Transact-SQL 是ANSI和ISO SQL 标准的Microsoft SQL server方言或扩展。

1.1 逻辑查询处理的各个阶段

 

  1.1.1逻辑查询处理阶段简介

 (1) from :from阶段标识出查询的来源表。处理表运算符。每个表运算符也会应用一系列子阶段。例如,在联接运算中涉及的阶段是(1-J1)笛卡尔积、(1-J2)on筛选器和(1-J3)添加外部行。from阶段生成虚拟表VT1。

       (1-J1)笛卡尔积:这个阶段对表运算符涉及的两个表执行笛卡尔积(交叉联接),生成虚拟表VT1-J1.

       (1-J2)ON 筛选器:这个阶段对VT1-J1中的行根据on 子句(<on_predicate>)中出现的谓词进行筛选。只有让该谓词取值为true的行,才能插入VT1-J2中。

       (1-J3)添加外部行:如果指定了outer join(相对于cross join或inner join ),则将保留表(preserved table)中没有找到匹配的行,作为外部行添加到VT1-J2,生成VT1-J3.

 (2) where:这个阶段根据在where子句中出现的谓词(<where_predicate>)对VT1中的行进行筛选。只有让谓词计算结果为true的行,才会插入VT2中。

 (3) group by: 按照group by 子句中指定的列名列表,将VT2中的行进行分组,生成VT3。最终,每个分组只有一个结果行。

 (4) having:根据having子句中出现的谓词(<having_predicate>)对VT3中的分组进行筛选。只有让谓词计算结果为TRUE的组,才会插入到VT4中。

 (5) select:处理select子句中的元素。生成VT5。

       (5-1)计算表达式: 计算select 列表中的表达式,生成VT5-1.

        (5-2) distinct:删除VT5-1中的重复行,生成VT5-2.

       (5-3)top:根据order by 子句定义的逻辑排序,从VT5-2中选择前面指定数量或百分比的行,生成表VT5-3.(如果没有order by,则top的顺序应该是存储的顺序?)

 (6)order by:根据order by子句中指定的列名列表,对VT5-3中的行进行排序,生成游标VC6.

1.3 逻辑查询处理阶段详解

 1.3.1 步骤1 FROM阶段

          三种筛选器:on、where、having

          注意:如果from子句中又多个表运算符,则按从左到右的顺序进行处理,每个表运算符的结果作为下一个表运算符的左输入,最终生成的虚拟表将作为下一阶段的输入。

三值逻辑:(Three-valued logic)

定义:在sql中谓词(逻辑表达式)的可能取值为true、false、unknown,这就是所谓的三值逻辑,是sql特有的属性。

     大多数编程语言中的逻辑表达式只有true和false两种取值。sql中的unknown逻辑值通常出现在涉及null值的逻辑表达式中(例如,以下这三个表达式的逻辑值都是unknown:null>2、null=null和x+null>y

).null这个符号代表一种缺失的值。当把一个缺失的值和另一个值(这个值也可能是null)进行比较时,逻辑结果总是unknown。

     unknown逻辑结果和null的处理非常容易引起混淆。虽然not true等于false,not false 等于true,但unknown的反面(not unknown)仍然是unknown。

     在不同的语言元素中,unknown逻辑结果和null 的处理方式也不尽相同。例如:所有的查询筛选器(on、where、having)都把unknown当做false处理。使筛选器取值为unknown的行会被排除在结果之外。而check约束中的unknown值实际上被当做true对待,假设表中包含一个check约束,要求salary列的值必须大于0.向该表插入salary为nnull的行时也可以成功。因为(null>0)等于unknown,在check约束中按true来处理。

     在筛选器中比较两个null值将得到unknown,而unknown按false来处理,就好像其中这两个null不相等一样。

     而另一方面,在unique约束、集合运算(如union和except)、以及排序和分组操作中,认为两个null是相等的。

     (1)如果表中又一列定义了unique约束,将无法向表中插入该列为null的两行。T-SQL在这一点上与标准不符。

     (2)group by子句会将所有null值分到一组。

     (3)order by子句会将所有null值排列到一起。 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

 

 1.3.2 步骤2:where阶段

           警告:因为还没有对数据进行分组,所以在where子句中不能使用聚合,例如,不能使用where orderdate=max(orderdate),也不能引用select列表中创建的别名,因为select列表这时还未被处理,例如,不能使用select year(orderdte) as orderyear。。。 where orderyear>2008.

          对于包含outer join 子句的查询,一个让人感到困惑的问题是:到底应该在on筛选器还是在where筛选器中指定逻辑表达式?

          两者的主要区别是on筛选器在添加外部行(步骤1-j3)之前应用,而在where筛选器则是在步骤(1-J3)之后才应用。on筛选器对保留表中部分行的删除并不是最终的,因为步骤(1-J3)会把这些行再添加回来,相反,where筛选器对行的删除时最终的,牢记这一点,将有助于做出正确的选择。(提示:只有当使用外联结时,on和where子句才会存在这种逻辑区别,当使用内联接时,在哪里指定逻辑表达式都一样,因为将会跳过步骤3,。在彼此相连的两个步骤中应用这些筛选器,中间没有其他任何步骤。)

 1.3.3 步骤3:group by 阶段

          这个阶段认为两个null值时相等的。也就是说,所有的null值会被分到同一组,就像一个已知的确定值一样。

 1.3.4 步骤4:having 阶段

          注意:count(*)会把外部行统计在内,即包含null值。故应指定列,count(orderid),这样就是准确的统计出每个客户的订单数。

 1.3.5 步骤5:select 阶段

          这里有一个同时操作的概念:例如,在大多数编程环境中,为了交换两个变量值,需要使用一个临时变量,而在sql中交换两个列值时,可以使用:

          update dbo.T1 set c1=c2,c2=c1,从逻辑上来说,应该假设所有操作是同时发生的。就好像是在整个操作完成之前,没有修改过表。接着再用计算结果替换原来的列值,基于类似的原因,以下update语句将更新T1中的所有行,为c1列加上更新开始时T1中的最大的c1值:update dbo.T1 set c1=c1+(select max(c1) from dbo.t1 );不用担心最大的c1值会随着操作的进行而持续变化,因为操作是同时瞬间发生的。

          top选项:百分比是向上取整。

在top中有一个选项:with ties ,指定从基本结果集中返回额外的行,对于 ORDER BY 列中指定的排序方式参数,这些额外的返回行的该参数值与 TOP n (PERCENT) 行中的最后一行的该参数值相同。只能在 SELECT 语句中且只有在指定了 ORDER BY 子句之后,才能指定 TOP...with ties。

 1.3.6 步骤6:排序用的order by 阶段

         该阶段可以用select中的别名,即别名处理是在select 阶段。

        这一步,与其他所有步骤不同的是,它返回的不是一个有效的表,而是一个游标。sql 的理论基础是集合论。集合中的行之间没有预先定义的顺序,它只是成员的一种逻辑组合,成员之间的顺序无关 紧要。对于带有排序作用的order by子句的查询,可以返回一个对象,其中的行按特定的顺序组织在一起。ANSI把这种对象称为游标(cursor)。理解这一步是正确理解sql 最基本的步骤之一。

        表表达式:包括视图、内联表值函数、派生表、cte。在sql中,表表达式中不允许使用带有ordere by子句的查询。而在T-SQL中,这一规定有一个例外,如果同时指定了top选项。

        记住:不要为表中的行假设任何特定的顺序。

        order by 子句认为两个null值是相等的。

1.4  逻辑查询处理的深入内容

  1.4.1 表运算符

   sql 2008中支持4种在查询的from子句使用的表运算符:join、apply、pivot、unpivot。注意,apply、pivot、unpivot不是ANSI标准运算符,它们是T-SQL中特种的扩展。

  1.4.3 集合运算符

   sql 2008支持4种集合运算符:union all、union、except、intersect。

 

转载于:https://www.cnblogs.com/free-birds/p/4593122.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注:分二卷,点击上传者查看第二卷地址。亲,本人纯手工添加了书签哦!!方便阅读  《Microsoft SQL Server 2008技术内幕:T-SQL语言基础》是Microsoft SQL Server 2008系列中的一本。书中全面深入地介绍了T-SQL的基本元素,以及SQL Server 2008中新增加的一些特性。主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理、可编程对象等内容。   书中并非系统地罗列T-SQL的各种语法元素,而是结合实践中的各种问题,教读者如何用SQL作为语言工具来思考问题,揭示基于集合查询的强大威力。本书内容丰富、文字简洁明快,列举的实例具有一定的难度,而且实用性较强,可以把它们作为解决实际问题的标准模板。阅读本书,可以充分地理解T-SQL语言和获得良好的编程实践,学会如何编写更加有效而强大的查询。书中大部分章节后面都提供了练习题目,可以帮助读者更好地掌握所学的内容。   《Microsoft SQL Server 2008技术内幕:T-SQL语言基础》适合须要学习T-SQL的各级程序员和数据库专业人员,是他们快速掌握T-SQL的必备参考图书。 致谢 引言 第1章 T-SQL查询和编程基础 1.1 理论背景 1.2 SQL SERVER体系结构 1.3 创建表和定义数据完整性 1.4 总结 第2章 单表查询 2.1 SELECT语句的元素 2.2 谓词和运算符 2.3 CASE表达式 2.4 NULL值 2.5 同时操作(ALL-AT-ONCE OPERATION) 2.6 处理字符数据 2.7 处理日期和时间数据 2.8 查询元数据 2.9 总结 2.10 练习 2.11 解决方案 第3章 联接查询 3.1 交叉联接 3.2 内联接 3.3 特殊的联接实例 3.4 外联接 3.5 总结 3.6 练习 3.7 解决方案 第4章 子查询 4.1 独立子查询 4.2 相关子查询 4.3 高级子查询 4.4 总结 4.5 练习 4.6 解决方案 第5章 表表达式 5.1 派生表 5.2 公用表表达式(CTE) 5.3 视图 5.4 内联表值函数 5.5 APPLY运算符 5.6 总结 5.7 练习 5.8 解决方案 第6章 集合运算 6.1 UNION(并集)集合运算 6.2 INTERSECT(交集)集合运算 6.3 EXCEPT(差集)集合运算 6.4 集合运算的优先级 6.5 避开不支持的逻辑查询处理 6.6 总结 6.7 练习 6.8 解决方案 第7章 透视、逆透视及分组集 7.1 透视转换 7.2 逆透视转换 7.3 分组集 7.4 总结 7.5 练习 7.6 解决方案 第8章 数据修改 8.1 插入数据 8.2 删除数据 8.3 更新数据 8.4 合并数据 8.5 通过表表达式修改数据 8.6 带有TOP选项的数据更新 8.7 OUTPUT子句 8.8 总结 8.9 练习 8.10 解决方案 第9章 事务和并发 9.1 事务 9.2 锁定和阻塞 9.3 隔离级别 9.4 死锁 9.5 总结 9.6 练习 第10章 可编程对象 10.1 变量 10.2 批处理 10.3 流程控制元素 10.4 游标 10.5 临时表 10.6 动态SQL 10.7 例程 10.8 错误处理 10.9 总结 附录A SQL SERVER使用入门 索引
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值