1、概念

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

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

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

2、数据

姓名    课程    分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94

3、嵌套的查询语句

select * from tb where 分数 in (select 分数 from tb where 分数>90)

上面的查询语句使用了一个子查询。虽然这条SQL语句并不复杂,但如果嵌套的层次过多,会使SQL语句非常难以阅读和维护。

因此,也可以使用表变量的方式来解决这个问题,SQL语句如下:

declare @t table (分数 int)
insert into @t (分数) (select 分数 from tb where 分数>90)
select * from tb where 分数 in (select * from @t)

虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又会带来另一个问题,就是性能的损失。

由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式并不太适合数据量大且频繁查询的情况。

为此,在SQL Server 中提供了另外一种解决方案,这就是公用表表达式(CTE),使用CTE,可以使SQL语句的可维护性,同时,CTE要比表变量的效率高得多。

with cr as
(
select 分数 from tb where 分数>90
)
select * from tb where 分数 in (select * from cr)

4、在使用CTE时应注意如下几点:

4.1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正常使用CTE:

with cr as
(
select 分数 from tb where 分数>90
)
select * from tb --应将这条SQL语句去掉
select * from tb where 分数 in (select * from cr) --使用CTE的SQL语句应紧跟在相关的CTE后面

4.2. CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示

with cr1 as
(
select * from tb
),
cr2 as
(
select * from tb
),
cr3 as
(
select * from tb
)
select a.* from cr1 a, cr2 b, cr3 c where a.分数 = b.分数 and a.分数 = c.分数

4.3. 如果CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE,当然,后面的SQL语句使用的就是数据表或视图了,如下面的SQL语句所示:

with tb as
(
select Name from Student
)
select * from tb

4.4. 如果将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾,如下面的SQL所示:

declare @t table (分数 int)
insert into @t (分数) (select 分数 from tb where 分数>90);--必须加分号
with tr as
(
select 分数 from tb where 分数 in (select * from @t)
)
select * from tr

最新文章

  1. Java常量字符串String理解
  2. webdriver(python)学习笔记一
  3. 在Ubuntu Desktop打开终端的2种方式
  4. crm操作安全角色
  5. Kotlin入门第四课:简单工厂模式
  6. 【CSS】Sticky Footer 布局
  7. codeforces581C
  8. [转]编程珠玑第五章二分搜索(折半查找)之java实现
  9. spring 中单例 bean 初始化之后和销毁之前执行指定动作 postconstruct 和 preDestroy
  10. Oracle设置某张表为只读
  11. Hive 数仓中常见的日期转换操作
  12. 通过BeanPostProcessor理解Spring中Bean的生命周期
  13. JQuery button控制div或者section
  14. JS--我发现,原来你是这样的JS(引用类型不简单[上篇],且听我娓娓道来)
  15. vc使用jsoncpp头文件冲突问题
  16. appium通过同级别(兄弟关系)元素找到元素
  17. 使用css技术代替传统的frame技术
  18. iOS-实现对象拷贝【对象拷贝】
  19. c# 读取confgi文件
  20. psp 第二周

热门文章

  1. 基于CAS的SSO单点登录-实现ajax跨域访问的自动登录(也相当于超时重连)
  2. jdk是什么?jdk1.8安装配置方法
  3. rac数据库默认sql tuning advisor,导致大量library cache lock
  4. http中COOKIE和SESSION有什么区别?(转知乎)
  5. vue.js--基础 事件结合双向数据绑定实现todolist 待办事项 已经完成 和进行中,键盘事件
  6. POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】
  7. js前端解析excel文件
  8. 【luogu P3371 单源最短路径 】 模板 SPFA优化
  9. 用java语言编写的简单二叉树
  10. Windows下安装PCL点云库