CTE好文两篇

转载 2007年09月13日 14:44:00
CTE(一)

通用表表达式(CTEs)是SQL Server 2005的一项新功能。它们类似于alias(如在Select T1.* FROM MyTable T1中),不过功能更为强大。本质上,CTE是一个临时结果集,它仅仅存在于它发生的语句中。您可以在Select、Insert、Delete、 Update或CTEATE VIEW语句中建立一个CTE。CTE类似于派生表,但拥有几项优点。

CTE的优点

与派生表不同,CTE能够引用自己本身。如果您不必存储视图,您可以用一个CTE来代替它。在一个语句中,您还可以多次引用CTE。应用CTE,您可以通过一个派生栏对结果进行分组。

之前,我曾写过有关原子和分子查询的文章。原子查询建立一个表,而分子查询建立在原子查询之上,提供清晰与重复利用。应用CTE也可以达到同样的目的。您可以将查询区域分割成可读的“块”,然后用这些块建立一个复杂的查询。执行递归查询是CTE最重要也是最强大的功能。

建立CTE

CTE通过关键字WITH建立,其模板为:

 

WITH CTE_name[ (column_name [,...n] ) ]
AS
( CTE_query_specification )

如果在CTE定义中提到的栏名称是唯一的,那么您可以不必给它们命名。不过,您同样也可以对它们重新命名。

下面的例子应用到SQL Server 2005中的AdventureWorks样本数据库。这个数据库被高度规格化,因此需要几个连接来集合与雇员有关的信息。视图简化了这一操作,但也收集了所有有关雇员的信息,而您可能仅仅需要其中一部分资料。

AdventureWorks的雇员数据分布在几个表中;而且,雇员与经理被存储在同一个表中(HumanResources.Employee),而他们的姓名(及其它数据)则存储在Person.Contact表中,这使得这个问题更加复杂。

首先,我们建立一个恢复雇员姓名的CTE。

 

WITH cte_Employee
AS
(
Selecte.EmployeeID, c.FirstName, c.MiddleName, c.LastName,
e.Title AS JobTitle, c.Phone, e.ManagerID
FROMHumanResources.EmployeeAS e
INNER JOIN Person.ContactAS c ON c.ContactID = e.ContactID
)

然后,我们可从CTE中选择一栏或几栏,就像它是一个标准的表或视图。

接着我们再进一步。我们需要雇员和他们经理的姓名,于是我们使用CTE两次,把它自身连接起来。下面是完整的查询代码:

 

WITH cte_Employee
AS
(
Selecte.EmployeeID, c.FirstName, c.MiddleName, c.LastName,
e.Title AS JobTitle, c.Phone, e.ManagerID
FROMHumanResources.EmployeeAS e
INNER JOIN Person.ContactAS c ON c.ContactID = e.ContactID
)
Select E.FirstName + ' ' E.LastName Employee,
M.FirstName + ' ' M.LastName Manager
FROMcte_Employee AS E
LEFT OUTER JOIN cte_Employee AS M
ON E.ManagerID = M.EmployeeID

限制:不能在一个语句中建立两个CTE。

CTE(二)

我先简单介绍一下CTE(Common Table Expression)是什么 ,然后简要介绍下用法和注意事项

什么是CTE:Common Table Expression:是Sql2005推出的语法,类似内置临时表,创建后自动消亡,在cte中可以进行递归查询等操作

cte可以看作临时表,但是它的生命周期仅存在于访问每一次的TSQL批处理语法中,而一般临时对象的生命周期与连接同在

一、生命周期

注意CTE和临时表有个重要的区别,就是生存周期,那么CTE的生存周期到底有多久呢,我们看下面的语句

--从帖子表中选出前30条放入一个叫CTE_Temp的临时表
with CTE_Temp AS(
Select Top(30* From Topics
)

--从CTE_temp中查出所有记录(第一次),没有问题,返回30条记录
select * from CTE_Temp

--从CTE_Temp中查询(第二次),报错,提示cte_temp对象不存在
select * from CTE_Temp

 

  紧跟在with语句后面的第一条语句是有效果的,执行第二条前对象就消亡了,也就是说cte的存在周期是with语句的下一条语句,所以,cte不能替代 临时表,但是适用于那种只用一次的临时表的场合,在这种情况下,使用cte不会造成日志文件的增大,也不需要手工销毁临时表

二、使用冒号分割

使用cte还有一个地方需要注意,如果在存储过程或者语句中,cte不是一个这个批处理的第一条语句,那么前一条语句必须要以冒号“;”结尾,如下

declare @a int
set @a=5
--从帖子表中选出前30条放入一个叫CTE_Temp的临时表
with CTE_Temp AS(
Select Top(30* From Topics
)

这 时执行报错:Incorrect syntax near the keyword 'with'. If this statement is a common table expression or an xmlnamespaces clause, the previous statement must be terminated with a semicolon.

如果你在set @a=5后面加一个;那么就可以顺利执行了,

三、使用限制

with语句下一定要有语句,并且一定要是select,update,delete,insert语句,如果没有语句会报:Incorrect syntax near ')'.但是如果你的with语句下跟了一个比如set 语句,如下

--从帖子表中选出前30条放入一个叫CTE_Temp的临时表
with CTE_Temp AS(
Select Top(30* From Topics
)
declare @a int
set  @a=5
会报告Incorrect syntax near the keyword 'declare'.

 

总结

CTE是SQL Server 2005的一项强大而灵活的功能。它使得SQL Server的可读性更强,更易于管理,降低了查询的复杂程度。如上所述,您可以在一个SQL Server语句中多次应用CTE。

 

关于mount/samba/字符集的两篇好文

第一篇:字符集和编码II: fat/msdos/vfat(链接至原作者博客) 具体到文件名乱码的问题,需要明确两点 第一,文件名作为一个字符串,需要被编码后存入文件系统; 第二,Li...
  • tsx86
  • tsx86
  • 2013年11月13日 21:54
  • 2357

mysql的cte(公用表表达式)

(一)公用表表达式是一个命名的临时结果集,仅在单个SQL语句(例如SELECT,INSERT,UPDATE或DELETE)的执行范围内存在。 查询中的列数必须与column_list中的列数相同。 ...
  • qq30211478
  • qq30211478
  • 2017年08月09日 13:51
  • 687

SQL Server CTE 递归查询全解

最近工作中遇到了一个问题,需要根据保存的流程数据,构建流程图。数据库中保持的流程数据是树形结构的,表结构及数据如下图: 仔细观察表结构,会发现其树形结构的特点: FFIRSTNODE:标记是否...
  • 3150379
  • 3150379
  • 2017年02月04日 20:09
  • 2251

SQL SERVER公用表表达式 (CTE)的用法和运用场景

sql server 2005开始推出了公用表表达式 (CTE),这个表达式是个人觉得挺有用的。 我主要是用于树结构的递归查询和简化sql语句增加可读性和可维护性。 公用表表达式其实提供的功能...
  • jsjpanxiaoyu
  • jsjpanxiaoyu
  • 2017年01月26日 17:55
  • 1414

SQL CTE学习总结

一句SQL完成动态分级查询 http://www.cnblogs.com/powertoolsteam/p/sqlite.html 在最近的活字格项目中使用ActiveReports报表设计器设计一个...
  • bcbobo21cn
  • bcbobo21cn
  • 2017年05月03日 21:12
  • 527

比较两篇文章的相似性方法

对于这个题目,开始毫无头绪,后来经过查阅资料现在讲方法总结如下:     1、利用余弦定理      我们知道向量a,b之间的夹角可用余弦定理求得:                  如果夹角的余弦值...
  • Jiakunboy
  • Jiakunboy
  • 2015年05月02日 16:08
  • 1683

Oracle 11g中CTE应用示例

关于SQL SERVER中的CTE中的CTE应用,请看这里:http://blog.csdn.net/downmoon/archive/2009/10/23/4715814.aspx 其实,ORAC...
  • sunpeng1117
  • sunpeng1117
  • 2015年11月13日 15:12
  • 622

SQLServer CTE递归和循环对比的优势--典型案例

首先,我们新建一张测试用的临时表#country,其中包含三个字段,AreaNam(地名) ,BelongTo(上级地名) ,Msg(地方简介)Create table #country (AreaN...
  • Wikey_Zhang
  • Wikey_Zhang
  • 2017年05月23日 14:35
  • 791

sql中with的用法(CTE公用表表达式):应用子查询嵌套,提高sql性能

一.WITH AS的含义 WITH AS短语,也叫子查询部分(subquery factoring),定义一个SQL片断,该片断会被整个SQL语句所用到。有时是为了让SQL语句的可读性更高些,也可能...
  • longshenlmj
  • longshenlmj
  • 2013年07月09日 21:41
  • 1621

cte递归嵌套查询例子

if exists(select 1 from sysobjects where id=OBJECT_ID('t_maxLevel') and xtype='u') drop table t_ma...
  • hdhai9451
  • hdhai9451
  • 2013年11月02日 17:22
  • 817
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CTE好文两篇
举报原因:
原因补充:

(最多只允许输入30个字)