简介

对于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. 在Sql Server 2005使用公用表表达式CTE简化复杂的查询语句

    公用表表达式CTE是Sql Server 2005引入的一种新的表表达式.CTE在许多方面都类似于派生表.逻辑上CTE是一个临时结果集,它仅仅存在于它发生的语句中.您可以在SELECT.INSERT. ...

  3. cte公用表表达式_CTE SQL删除; 在SQL Server中删除具有公用表表达式的数据时的注意事项

    cte公用表表达式 In this article, the latest in our series on Common table expressions, we'll review CTE SQ ...

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

    原文: SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用 本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开 ...

  5. 公用表表达式(CTE)WITH:树型查询、更新

    转自http://msdn.microsoft.com/zh-cn/library/ms175972(SQL.100).aspx 指定临时命名的结果集,这些结果集称为公用表表达式 (CTE). 语法: ...

  6. mysql cte 语法,mysql8 公用表表达式CTE的使用方法实例分析

    本文实例讲述了mysql8 公用表表达式cte的使用方法.分享给大家供大家参考,具体如下: 公用表表达式cte就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟 ...

  7. cte mysql_mysql8 公用表表达式CTE的使用

    公用表表达式CTE就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的,CTE可以引用其他CTE,但子查询不能引用其他子查询. 一.cte的语 ...

  8. mysql cte_mysql8 公用表表达式CTE的使用方法实例分析

    本文实例讲述了mysql8 公用表表达式CTE的使用方法.分享给大家供大家参考,具体如下: 公用表表达式CTE就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟 ...

  9. T-SQL之公用表表达式(CTE)

    题外话: 以前也写过几篇,后来总算觉得写得不够好,写了点又删了点,最后一直没有东西留下来,随着时间的流逝,几乎没有积累.最近在看T-SQL相关的书,结合工作中遇到的问题,我打算写点东西来记录我的学习经 ...

最新文章

  1. [linux内核][linux中断]——软中断机制
  2. 速度前瞻运动控制c语言程序_整合实时运动控制及多颗相机连接,大幅提升光学影像检测速度...
  3. bzoj 36733674: 可持久化并查集 by zky
  4. Bzoj4817:[SDOI2017]树点涂色
  5. select,poll,epoll用法
  6. 教你必备Excel表格技巧。
  7. Leetcode--24. 两两交换链表中的结点
  8. 5 分钟全面掌握 Python 装饰器
  9. rabbit mq 入门
  10. linux下解压7z压缩包分卷
  11. Java之设计模式一
  12. 聊聊Elasticsearch的CachedSupplier
  13. el-dialog 一些问题 局中滚动
  14. FGSM论文阅读笔记
  15. 数据分析项目整理之用户消费行为分析
  16. 关于file_get_contents(php://input)
  17. linux驱动之输入子系统
  18. vector注意事项,vector subscript out of range
  19. 转:TED高赞演讲:我们的认知,正在被这3种偏见毁掉
  20. ZAFU_2021_1_26_2021寒假个人赛第二场题解

热门文章

  1. Spring 4.2.2以上版本和swagger集成方案和踩过的坑
  2. 深度有趣 | 22 天马行空的DeepDream
  3. Windows Server 2016之RDS部署之添加RD网关
  4. WPF MvvmLight简单实例(1) 页面导航
  5. CUPS Share Printer
  6. 利用python+seleniumUI自动化登录获取cookie后再去测试接口,今天终于搞定了
  7. firefox+firebug
  8. Linux之SELinux的基本应用
  9. CS224n Assignment 2
  10. schema类SpringMVC+Hibernate+Spring整合(二)