理解T-SQL的逻辑查询顺序是学习SQL Server的基础。

  T-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>

  注释

  (1) 执行笛卡尔乘积。如果有多个表JOIN, 则逻辑执行顺序可以理解成: 先执行INNER JOIN, 再执行OUTER JOIN;或者理解成:按表出现的顺序逐个JOIN。当然,实际的执行顺序有赖于实际的执行计划,同一个SQL在不同的“环境”(索引、统计信息等)下,可能产生不同的执行计划。SQL Server的JOIN方式包括:INNER JOIN,LEFT JOIN,RIGHT JOIN,,FULL JOIN,CROSS JOIN,还有值得一提表运算符APPLY:CROSS APPLY,OUTER APPLY。

  (2) 应用ON筛选器。注意把过滤条件放在ON和放在WHERE中的区别: 对于INNER JOIN,过滤条件放在哪里结果都正确;对于OUTER JOIN就要注意了:放在ON中,就是先过滤再JOIN,放在WHERE中,就是先JOIN再过滤,得到的结果很可能是不一样的。当然,生成实际的执行计划时,优化器会自动根据实际情况,把SQL中的LEFT JOIN改成INNER JOIN联接,但是,我的建议是:写SQL时,用INNER JOIN还是LEFT JOIN一定要依据实际的业务逻辑。在此还要注意一下三值逻辑:在筛选器中UNKNOW=FALSE, 在CHECK约束中UNKNOW=TRUE,UNIQUE约束, 排序操作和分组操作认为两个NULL是相等的。

  (3) 添加外部行。外部联接包含: LEFT,RIGHT,FULL。为了说明“添加外部行”的概念,举个例子:A表有4行记录,B表有3行记录,且与A表中的3行记录一一对应。当A表LEFT JOIN B表时,它们实际上进行了两步操作:1.先INNER JOIN,结果产生3行记录,2.添加外部行:把A表中那1行没有与B表对应的记录“添加”到结果集末尾,最终结果集为4行记录。所以,大家经常说INNER JOIN比LEFT JOIN效率高,原因也就在于此,LEFT JOIN多了一个添加外部行的操作。

  (4) 应用WHERE筛选器。再次注意过滤条件放在ON和放在WHERE中的区别:ON在第(2)步被应用, 而WHERE是在第(4)步被应用。

  (5) 分组。注意SELECT语句和GROUP语句中的分组字段或表达式要一致,在不影响分组逻辑的前提下,也允许出现小小的不一致,如: SELECT YEAR(orderdate)+1 FROM table_name GROUP BY YEAR(orderdate)。如果用GROUP BY ALL(非标准遗留物),则相当于跳过第(4)步WHERE过滤,测试时可以一用。

  (6) 应用CUBE或ROLLUP。注意GROUPING聚合函数在这里的应用:如果是由CUBE或ROLLUP产生的NULL,返回1,否则0。

  (7) 应用HAVING筛选器。注意COUNT(*)、COUNT(1)和COUNT(field_name)的区别:前两者无区别,COUNT(field_name)统计时忽略值为NULL的记录。

  (8) 处理SELECT列表。注意某些函数只会产生一个值,如GETDATE(),某些函数函数会产生多个值,如NEWID()。

  (9) 应用DISTINCT子句。注意DISTINCT应该在TOP之前。

  (10)应用ORDER BY子句。唯一一个可利用SELECT列列表中的别名的地方。如果有DISTINCT关键字, ORDER BY中只能出现SELECT列列表中的列。ORDER BY中可以使用数字代表SELECT列表中出现的列,但不推荐。因为ORDER BY只返回游标,所以结果不能用作表表达式(视图、内联表值函数、子查询、派生表、CTE), 但带TOP的选项除外,因为使用TOP后将返回一个结果集, 而并非游标:SELECT * FROM (SELECT TOP(10) * FROM dbo.table_name ORDER BY id DESC) T

  (11)应用TOP选项。可以使用WITH TIES,但必须有ORDER BY:除了返回指定条数的记录,再返回与最后一条记录排序相等的所有记录。TOP()中的参数可以是表达式。如果不指定ORDER BY,查询结果顺序将是不确定的,因为生成的执行计划可能不一样,返回的行是SQL Server物理上最先访问到的行。所以说:有赖于排序的结果集一定要加上ORDER BY。

  小结

  当你写的SQL语法或结果集出现问题时,仔细分析一下T-SQL逻辑执行顺序,就会明白为什么^_^

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. Network Real Trace Analysis 2015年12月10日

    了解网络中真实的流量,国内很难找到巨人的肩膀. WAND是新西兰waikato 大学计算机系的研究小组,主要做网络测量,大规模网络流量捕获,网络分析.还做专业的分析软件. libtrace是其开源的分 ...

  2. Spring源码研究--下载-编译-导入eclipse-验证

    一,环境配置 操作系统:Unbutu14.04LTS JDK: 1.8.0_40 git: 1.9.1 gradle: 2.2.1 二,源码下载-编译-导入eclipse-验证 1,下载 使用git直 ...

  3. HALCON形状匹配(转)

    LIntExport Herror create_shape_model( const Hobject&  Template ,  //reduce_domain后的模板图像 Hlong  N ...

  4. c#中的序列化

    1.对象的序列化 NET支持对象序列化有以下几种方式:二进制序列化:对象序列化之后是二进制形式的,通过BinaryFormatter类来实现的,这个类位于System.Runtime.Serializ ...

  5. leetcode162

    class Solution { public: int findPeakElement(vector<int>& nums) { int n = nums.size(); ) { ...

  6. Consul 简介、安装、常用命令的使用

    1 Consul简介 Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,Consul的方案更"一站式" ...

  7. AngularJS的 $resource服务 关于CRUD操作

    AngularJs 的CRUD 操作 是指对数据库的操作: CRUD其实是数据库基本操作中的Create(创建).ReadRetrieve(读取).Update(更新).Delete(删除).而这里的 ...

  8. 超强敏感词过滤算法第二版 可以忽略大小写、全半角、简繁体、特殊符号、HTML标签干扰

    上一篇 发一个高性能的敏感词过滤算法 可以忽略大小写.全半角.简繁体.特殊符号干扰 改进主要有几点: 用BitArray取代Dictionary用空间换时间 性能进一步提升 大概会增加词库的  6k* ...

  9. Opencv Harris角点检测

    #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...

  10. 669. Trim a Binary Search Tree修剪二叉搜索树

    [抄题]: Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so ...