共用表表达式(CTE)可以看成是一个临时的结果集,可以再SELECT,INSERT,UPDATE,DELETE,MARGE语句中多次引用。

一好处:使用共用表表达式可以让语句更加清晰简练。

1.可以定义递归公用表表达式(CTE)

2.当不需要将结果集作为视图被多个地方引用时,CTE可以使其更加简洁  

3.GROUP BY语句可以直接作用于子查询所得的标量列

4.可以在一个语句中多次引用公用表表达式(CTE)

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

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

在MSDN中的原型:

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

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

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

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

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

1
2
3
4
5
WITH cte_Test AS
(
SELECT FROM dbo.SysOrganization
)
SELECT FROM cte_Test

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

只能接下来一条使用:

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

递归公用表表达式(CTE)

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

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

  • 基本语句
  • 递归语句

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

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

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

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

ith
cte1 as
(
select * from table1 where name like 'abc%'
),
cte2 as
(
select * from table2 where id > 20
),
cte3 as
(
select * from table3 where price < 100
)
select a.* from cte1 a, cte2 b, cte3 c where a.id = b.id and a.id = c.id

3. 不能在 CTE_query_definition 中使用以下子句:

(1)COMPUTE 或 COMPUTE BY

(2)ORDER BY(除非指定了 TOP 子句)

(3)INTO

(4)带有查询提示的 OPTION 子句

(5)FOR XML

(6)FOR BROWSE

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

declare @s nvarchar(3)
set @s = 'C%'
; -- 必须加分号
with
t_tree as
(
select CountryRegionCode from person.CountryRegion where Name like @s
)
select * from person.StateProvince where CountryRegionCode in (select * from t_tree)

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

declare @s nvarchar(3)
set @s = 'C%'
; -- 必须加分号
with
t_tree as
(
select CountryRegionCode from person.CountryRegion where Name like @s
)
select * from person.StateProvince where CountryRegionCode in (select * from t_tree)

最后贴出一个递归相关的语句

WITH CTE_Organization([SpClassifyId],[ParentClassifyId],[ClassifyName],ClassifyStatus,IsSiteInspection,IsPerformance,IsAfterPerformance,IsPmInterview,Iscbfy,IsStorage,IsRequired )
AS
(SELECT [SpClassifyId],[ParentClassifyId],[ClassifyName],ClassifyStatus,IsSiteInspection,IsPerformance,IsAfterPerformance,IsPmInterview,Iscbfy,IsStorage,IsRequired
FROM dbo.SM_SupplierClassify
WHERE [ClassifyName] like '%电梯工程%' and ClassifyStatus='Active'
UNION ALL
SELECT o.[SpClassifyId],o.[ParentClassifyId],o.[ClassifyName],o.ClassifyStatus,o.IsSiteInspection,o.IsPerformance,o.IsAfterPerformance,o.IsPmInterview,o.Iscbfy,o.IsStorage,o.IsRequired
FROM dbo.SM_SupplierClassify o INNER JOIN CTE_Organization oo ON o.[SpClassifyId]=oo.[ParentClassifyId])
SELECT distinct * FROM CTE_Organization

上述递归相关的表脚本为:

CREATE TABLE [dbo].[SM_SupplierClassify](
[SpClassifyId] [varchar](100) NOT NULL,
[ClassifyName] [nvarchar](50) NOT NULL,
[ClassifyFullName] [nvarchar](100) NULL,
[ContactPerson] [nvarchar](50) NULL,
[ContactPhone] [varchar](50) NULL,
[ParentClassifyId] [varchar](100) NULL,
[ClassifyLevel] [int] NULL,
[FullName] [nvarchar](200) NULL,
[FullId] [varchar](2000) NULL,
[ClassifyStatus] [varchar](50) NULL,
[ClassifyRemark] [nvarchar](200) NULL,
[IsSiteInspection] [bit] NULL,
[IsPerformance] [bit] NULL,
[IsAfterPerformance] [bit] NULL,
[IsPmInterview] [bit] NULL,
[SeqNo] [int] NULL,
[Isdeleted] [bit] NULL,
[CreateUserId] [int] NULL,
[CreateUserName] [nvarchar](50) NULL,
[CreateDate] [datetime] NULL,
[ModifyUserId] [int] NULL,
[ModifyUserName] [nvarchar](50) NULL,
[ModifyDate] [datetime] NULL,
[ForefatherClassifyName] [nvarchar](50) NULL,
[SupplierClassNo] [nvarchar](100) NULL,
[Iscbfy] [bit] NULL,
[IsStorage] [bit] NULL,
[IsRequired] [bit] NULL,
[IsMoreContract] [bit] NULL,
PRIMARY KEY CLUSTERED
(
[SpClassifyId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO

数据为:https://files.cnblogs.com/files/chenwolong/%E6%95%B0%E6%8D%AE.zip

@陈卧龙的博客

SqlServer共用表达式(CTE)With As 处理递归查询的更多相关文章

  1. SqlServer共用表达式(CTE)With As

    共用表表达式(CTE)可以看成是一个临时的结果集,可以再SELECT,INSERT,UPDATE,DELETE,MARGE语句中多次引用. 一好处:使用共用表表达式可以让语句更加清晰简练. 1.可以定 ...

  2. SQLServer中的CTE通用表表达式

    开发人员正在研发的许多项目都涉及编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种情形是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Tr ...

  3. SQLServer中的CTE(Common Table Expression)通用表表达式使用详解

    概述 我们经常会编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种方案是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Transact-S ...

  4. 公用表表达式 (CTE)、递归、所有子节点、sqlserver

    指定临时命名的结果集,这些结果集称为公用表表达式 (CTE).公用表表达式可以包括对自身的引用.这种表达式称为递归公用表表达式. 对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分 ...

  5. Sql Server 公用表达式(CTE)

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

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

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

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

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

  8. 公用表表达式CTE

    公用表表达式CTE表面上和派生表非常相似,看起来只是语义上的区别.但和派生表比较起来,CTE具有几个优势:第一,如果须要在一个CTE中引用另一个CTE,不需要像派生表那样嵌套,相反,只要简单地在同一个 ...

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

    公用表表达式(CTE) 在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式( ...

随机推荐

  1. 在CentOS7.5上安装Docker,在Docker中拉取CentOS7.5镜像并安装SSH服务

    # 安装docker yum install -y docker # 启动docker systemctl start docker # 加入开机启动 systemctl enable docker ...

  2. HS编码查询hs海关编码列表

    HS编码查询是外面人一个必须技能,以下是ytkah整理的hs海关编码列表,罗列了几乎所有的hs商品编码,方便大家查询,也欢迎大家转给有需要的朋友! 编号 名称 01022100 荷斯坦青年牛 0103 ...

  3. Spring AOP技术本质认识

    Spring AOP技术本质认识 一.AOP简介   AOP(Aspect Oriented Programming,面向切面编程),把某一类问题集中在一个地方进行处理,比如处理程序中的点击事件.打印 ...

  4. eclipse IDE for java developers下载与安装

    1.进入eclipse官网下载页面 https://www.eclipse.org/downloads/ 2.点击Download Packages 3.windows 用户 选择 64 bits 4 ...

  5. 开始Golang之旅了

  6. Pandas | 14 统计函数

    统计方法有助于理解和分析数据的行为.可以将这些统计函数应用到Pandas的对象上. pct_change()函数 系列,DatFrames和Panel都有pct_change()函数.此函数将每个元素 ...

  7. 有这样一个url=http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段js程序提取url 中的各个get参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中, 如{a:'1',b:'2',c:'',d:'xxx',e:undefined}

    第一种方法: console.log(getJson(url)); function getJson(url){ var obj={}; var arr=url.split("?" ...

  8. Linux 进程树查看工具 pstree

    pstree 是 Linux 下的一个用于展示进程树结构的工具,类似于 tree 展示目录树一样,可视化地查看进程的继承关系.pstree 工具其实是 PSmisc 工具集的成员之一,PSmisc 工 ...

  9. parameter与argument,property与attribute

    本文摘自:https://blog.csdn.net/Zhangxichao100/article/details/59484133 parameter与argument,property与attri ...

  10. springboot做api服务时不使用thymeleaf的相关警告DefaultTemplateResolverConfiguration 的消除

    springboot在不配置thymeleaf相关属性的情况下,会提示如下的问题 DefaultTemplateResolverConfiguration - Cannot find template ...