简介


对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的. 但是,视图是作为系统对象存在数据库中,那对于结果集仅仅需要在存储过程或是用户自定义函数中使用一次的时候,使用视图就显得有些奢侈了.

公用表表达式(Common Table Expression)是SQL SERVER 2005版本之后引入的一个特性.CTE可以看作是一个临时的结果集,可以在接下来的一个 SELECT,INSERT,UPDATE,DELETE,MERGE语句中被多次引用。使用公用表达式可以让语句更加清晰简练.

除此之外,根据微软对CTE好处的描述,可以归结为四点:

  • 可以定义递归公用表表达式(CTE)
  • 当不需要将结果集作为视图被多个地方引用时,CTE可以使其更加简洁
  • GROUP BY语句可以直接作用于子查询所得的标量列
  • 可以在一个语句中多次引用公用表表达式(CTE)

公用表表达式(CTE)的定义


公用表达式的定义非常简单,只包含三部分:

  1. 公用表表达式的名字(在WITH之后)
  2. 所涉及的列名(可选)
  3. 一个SELECT语句(紧跟AS之后)

在MSDN中的原型:

WITH expression_name [ ( column_name [,...n] ) ] 

AS 

( CTE_query_definition ) 

按照是否递归,可以将公用表(CTE)表达式分为递归公用表表达式和非递归公用表表达式.

非递归公用表表达式(CTE)


非递归公用表表达式(CTE)是查询结果仅仅一次性返回一个结果集用于外部查询调用。并不在其定义的语句中调用其自身的CTE

非递归公用表表达式(CTE)的使用方式和视图以及子查询一致

比如一个简单的非递归公用表表达式:

当然,公用表表达式的好处之一是可以在接下来一条语句中多次引用:

前面我一直强调“在接下来的一条语句中”,意味着只能接下来一条使用:

由于CTE只能在接下来一条语句中使用,因此,当需要接下来的一条语句中引用多个CTE时,可以定义多个,中间用逗号分隔:

递归公用表表达式(CTE)


递归公用表表达式很像派生表(Derived Tables ),指的是在CTE内的语句中调用其自身的CTE.与派生表不同的是,CTE可以在一次定义多次进行派生递归.对于递归的概念,是指一个函数或是过程直接或者间接的调用其自身,递归的简单概念图如下:

递归在C语言中实现的一个典型例子是斐波那契数列:

long fib(int n)   
{  
if (n==0) return 0;
  if (n==1) return 1;   
if (n>1) return fib(n-1)+fib(n-2);
}

上面C语言代码可以看到,要构成递归函数,需要两部分。第一部分是基础部分,返回固定值,也就是告诉程序何时开始递归。第二部分是循环部分,是函数或过程直接或者间接调用自身进行递归.

对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分:

  • 基本语句
  • 递归语句

在SQL这两部分通过UNION ALL连接结果集进行返回:

比如:在AdventureWork中,我想知道每个员工所处的层级,0是最高级

这么复杂的查询通过递归CTE变得如此优雅和简洁.这也是CTE最强大的地方.

当然,越强大的力量,就需要被约束.如果使用不当的话,递归CTE可能会出现无限递归。从而大量消耗SQL Server的服务器资源.因此,SQL Server提供了OPTION选项,可以设定最大的递归次数:

还是上面那个语句,限制了递归次数:

所提示的消息:

这个最大递归次数往往是根据数据所代表的具体业务相关的,比如这里,假设公司层级最多只有2层.

总结


CTE是一种十分优雅的存在。CTE所带来最大的好处是代码可读性的提升,这是良好代码的必须品质之一。使用递归CTE可以更加轻松愉快的用优雅简洁的方式实现复杂的查询。

T-SQL查询进阶--详解公用表表达式(CTE)的更多相关文章

  1. 详解公用表表达式(CTE)

    简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...

  2. 存储过程——公用表表达式(CTE)

    目录 0. 背景说明 1. 定义及语法细节 1.1 基本定义 1.2 基本语法 1.3 多个CTE同时声明 1.4 CTE嵌套使用 2. CTE递归查询 2.1 简介 2.2 准备工作 2.3 计算每 ...

  3. SQL Server进阶(六)表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数

    概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...

  4. SQL Server温故系列(3):SQL 子查询 & 公用表表达式 CTE

    1.子查询 Subqueries 1.1.单行子查询 1.2.多行子查询 1.3.相关子查询 1.4.嵌套子查询 1.5.子查询小结及性能问题 2.公用表表达式 CTE 2.1.普通公用表表达式 2. ...

  5. SQL Server 公用表表达式(CTE)实现递归

    公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...

  6. SQL Server 公用表表达式(CTE)实现递归的方法

    公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...

  7. SQL Server 表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数

    概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...

  8. SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用

    本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等 ...

  9. sql server使用公用表表达式CTE通过递归方式编写通用函数自动生成连续数字和日期

    问题:在数据库脚本开发中,有时需要生成一堆连续数字或者日期,例如yearly report就需要连续数字做年份,例如daily report就需要生成一定时间范围内的每一天日期.而自带的系统表mast ...

随机推荐

  1. javaee学习-JSP指令简介

    JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: page指令 Inclu ...

  2. 00_ForTest

    -----该页是爬虫的测试页请忽略------- 1234545@qq.comadasdsdasdsad阿打算多少其热情为 asdasdasdasd4w5wsdvv啊实打实大 啊实打实大asdasda ...

  3. bzoj1697:[Usaco2007 Feb]Cow Sorting牛排序 & bzoj1119:[POI2009]SLO

    思路:以bzoj1119为例,题目已经给出了置换,而每一次交换的代价是交换二者的权值之和,而置换一定是会产生一些环的,这样就可以只用环内某一个元素去置换而使得其余所有元素均在正确的位置上,显然要选择环 ...

  4. 带缓冲的IO和不带缓冲的IO

    文件描述符: 文件描述符是一个小的非负整数,是内核用来标识特定进程正在访问的文件 标准输入/输出/出错: shell为每个程序打开了三个文件描述符,STDIN_FILEON,STDOUT_FILEON ...

  5. 九度OJ 1370 数组中出现次数超过一半的数字

    题目地址:http://ac.jobdu.com/problem.php?pid=1370 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2 ...

  6. OpenCV2学习笔记01:Linux下OpenCV开发环境的搭建

    个人已经厌倦了Windows下的开发方式,于是决定转到Linux平台上来,当然我也知道这个转变会很艰辛,但是我还是要坚持.所以,后面的所有开发我都会基于Linux和Qt,先从开发环境的搭建开始做起,当 ...

  7. 青瓷qici - H5小游戏 抽奖机 3 效果设置

    现在是万事俱备,只欠东风,好,我们一起动手,先来东风东. 烟花粒子效果 第一个来实现我们的烟花粒子效果,点击我们的粒子,按照下图方式配置. 注意此时我们已经加入了white.png作为粒子特效使用. ...

  8. Linux下使用openvpn客户端

    安装 root 权限用户下 :yum install openvpn fedora23的yum可能会切换到dnf源上安装不必在意,等待就ok. 稍等片刻将自动安装好openvpn需要的软件包.安装完成 ...

  9. 玩转HTML5移动页面(动效篇)

    原文:http://www.grycheng.com/?p=458 作为一名前端,在拿到设计稿时你有两种选择: 1.快速输出静态页面 2.加上高级大气上档次狂拽炫酷屌炸天的动画让页面动起来 作为一个有 ...

  10. (转载)DBGridEh导出Excel等格式文件

    DBGridEh导出Excel等格式文件 uses DBGridEhImpExp; {--------------------------------------------------------- ...