引言

本文是对《Microsoft SQL SERVER 2008技术内幕 T-SQL查询》中的第一章做的阅读笔记,这一章的主要内容是分析SQL查询中各子句的执行顺序。如果你对此已了然于胸了,那可以直接略过本文;如果你时间比较珍贵,则可以大致看一下流程图;如果你想更详细地了解,则可以去阅读“T-SQL查询”这本书。

下面我写了几道测试题,如果你对于这些问题不知其所以然,那我还是建议你看看这本书,再不济也应该好好看看本文。(越想走得远,就越应该重视基础)

测试题

1、  对full join、cross join(select * from orders,customers)是否有一个清晰的认识?
  SELECT * FROM Orders CROSS JOIN Customers ON Orders.customerid=Customers.customerid;(错)

2、  在创建视图时,如果不包含top时,为什么就不能使用order by?
  CREATE VIEW V AS SELECT * FROM  orders ORDER BY orderId;(错)
  CREATE VIEW V AS  SELECT TOP 10 * FROM orders ORDER BY orderId ;(对)

3、  为什么select列表中的别名不能在where子句中使用?
  SELECT customerId AS Id FROM orders WHERE Id>5;(错)

4、  使用了group by 子句的查询语句中,为什么having或select子句中列只能是group by 子句中的列或是包裹在聚合函数中?
  SELECTorderId,customerId FROM orders GROUP BY orderId HAVING customerId =15;(错)

5、  在多表联接查询时,什么情况下过滤条件加在where或on上的作用是一样的?

逻辑查询处理

步骤序号:

流程图:

处理阶段简介:

(1)FROM             处理表运算符生成虚拟表VT1。以Join运算符为例,join有三个子阶段

  (1-J1)笛卡尔积       两个表执行笛卡尔积(交叉联接),生成虚拟表VT1-J1。

  (1-J2)ON选器      对VT1-J1中的行根据ON子句中的条件进行筛选,只有条件为true的行,才能插入VT1-J2中。

  (1-J3)添加外部行    如果指定了outer join,则将保留表(比如用left join时,则左表为保留表)中没有匹配的行,作为外部行添加到VT1-J2,生成VT1-J3。

(2)WHERE             根据where子句中的条件,对VT1中的行进行筛选,只有条件为true的行才会插入VT2中。

(3)GROUP BY      对VT2中的行进行分组,生成VT3。最终,每个分组只有一个结果行。

(4)HAVING         根据having子句的条件,对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。

(6)ORDER BY     根据order by子句中的列,对VT5-3中的列进行排序,生成游标VC6。

其它表运算符的逻辑查询处理简介

APPLY

APPLY涉及下面两个步骤中的一步或两步(取决于APPLY类型):

  1. A1: 用左表中的每一行应用与右边的表达式,最后组合生成虚拟表A1。
  2. A2:添加外部行。(针对于OUTER APPLY)

PIVOT

示例:SELECT * FROM Orders PIVOT (SUM(val)  FOR orderYear IN ([2006],[2007]) )AS P

PIVOT涉及以下三个逻辑阶段:

  1. P1:分组。隐式地对Orders中的行进行分组,分组依据是那些未作为pivot输入的所有列,分组生成虚拟表P1。(从示例查询语句中可以看到Pivot运算符引用Orders的两个列作为输入参数(val,orderYear))。
  2. P2:扩展。把in列表中的值扩展到它们相应的目标列上。在逻辑上,相当于为in子句中指定的每个目标列使用了case表达式: CASE WHEN orderYear= 2006  THEN  val  END
  3. P3:聚合。对每个case表达式应用指定的聚合函数,生成结果列。SUM(CASE WHEN orderYear= 2006  THEN  val  END)  AS [2006]。

UNPIVOT

示例:SELECT * FROM  数据源表 UNPIVOT( val FOR orderYear IN ([2006],[2007])) AS U

UNPIVOT涉及以下三个逻辑阶段:

  1. U1:生成副本。循环In中的列名,每一列都会生成一个左表的副本。这一步生成的虚拟表如表U1所示。
  2. U2:提取元素。从来源列中提取出与行的当前副本所代表的转换元素相对应的值。这一步生成的虚拟表如表U2所示。
  3. U3:删除带NULL的行。这一步生成的虚拟表如表U3所示。

T-SQL逻辑查询处理的更多相关文章

  1. 45、SQL逻辑查询语句执行顺序

    一 SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOI ...

  2. 第四篇:记录相关操作 SQL逻辑查询语句执行顺序

    http://www.cnblogs.com/linhaifeng/articles/7372774.html 一 SELECT语句关键字的定义顺序 SELECT DISTINCT <selec ...

  3. SQL逻辑查询语句执行顺序

    阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SELECT语句关键字的定义顺序 SELE ...

  4. 9、SQL逻辑查询语句执行顺序

    本篇导航: SELECT语句关键字的定义顺序 SELECT语句关键字的执行顺序 准备表和数据 准备SQL逻辑查询测试语句 执行顺序分析 一.SELECT语句关键字的定义顺序 SELECT DISTIN ...

  5. SQL逻辑查询语句执行顺序 需要重新整理

    一.SQL语句定义顺序 1 2 3 4 5 6 7 8 9 10 SELECT DISTINCT <select_list> FROM <left_table> <joi ...

  6. {MySQL的逻辑查询语句的执行顺序}一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析

    MySQL的逻辑查询语句的执行顺序 阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SEL ...

  7. mysql SQL 逻辑查询语句和执行顺序

    关键字的执行优先级(重点) fromwheregroup byhavingselectdistinctorder bylimit 先创建两个表 CREATE TABLE table1 ( custom ...

  8. sql逻辑查询语句的执行顺序

    SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN ...

  9. SQL学习笔记四(补充-1-1)之MySQL单表查询补充部分:SQL逻辑查询语句执行顺序

    阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SELECT语句关键字的定义顺序 SELE ...

  10. mysql五补充部分:SQL逻辑查询语句执行顺序

    一 SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOI ...

随机推荐

  1. Python笔记·第六章——集合 (set) 的增删改查及 copy()方法

    简介: 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 1.去重,把一个列表变成集合,就自动去重了. ...

  2. Python笔记·第三章—— 逻辑运算

    一.逻辑运算符的种类及优先级 ▷逻辑运算符包括 not and or  ▷他们的优先级是 () > not > and > or 二.普通逻辑运算 ▷A and B --->  ...

  3. ME01:猎场中猎头的内核

    前几天追了下<猎场>,只看了前面10多集,觉得下面的对话有点意思. 是关于猎头是干什么的? 猎头具备的素质. 对我们普通人是不是也有启发意义呢? 如何看人, 找到靠谱的合作人?找打好的老板 ...

  4. ABP 框架启程

    准备动手写一套电商的系统,辗转收集了不少相关的开源项目,最后决定使用ABP作为起点. 在园子里好多人都在推广ABP.有个园友做了一个集合贴,方便大家使用  ABP集合贴 建议大家优先看 HK Zhan ...

  5. (转)解决jdk1.8中发送邮件失败(handshake_failure)问题

    解决jdk1.8中发送邮件失败(handshake_failure)问题 作者 zhisheng_tian 2016.08.12 22:44* 字数 1573 阅读 2818评论 6喜欢 9 暑假在家 ...

  6. angular自定义分页组件(实用)

    功能描述:分页,点击按钮或者下一页获取分页接口,同时active到对应页码. html模块: <page page-count="totalPage" on-click-pa ...

  7. [LeetCode] 二叉树相关题目(不完全)

    最近在做LeetCode上面有关二叉树的题目,这篇博客仅用来记录这些题目的代码. 二叉树的题目,一般都是利用递归来解决的,因此这一类题目对理解递归很有帮助. 1.Symmetric Tree(http ...

  8. Data Base mongodb高版本与低版本的区别

    mongodb高版本与低版本的区别 一.mongodb引擎: Mongodb 3.0支持用户自定义存储引擎,用户可配置使用mmapv1或者wiredTiger存储引擎. 3.2版本以后默认的开启的是w ...

  9. 添加MD5 密码加密

        编辑 /etc/grub/grub.conf 配置文件 password = 123456 password --md5 $5$H.........SS grub-crypt  --md5   ...

  10. redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...