SqlServer共用表达式(CTE)With As 处理递归查询
共用表表达式(CTE)可以看成是一个临时的结果集,可以再SELECT,INSERT,UPDATE,DELETE,MARGE语句中多次引用。
一好处:使用共用表表达式可以让语句更加清晰简练。
1.可以定义递归公用表表达式(CTE)
2.当不需要将结果集作为视图被多个地方引用时,CTE可以使其更加简洁
3.GROUP BY语句可以直接作用于子查询所得的标量列
4.可以在一个语句中多次引用公用表表达式(CTE)
二定义:公用表达式的定义非常简单,只包含三部分:
- 公用表表达式的名字(在WITH之后)
- 所涉及的列名(可选)
- 一个SELECT语句(紧跟AS之后)
在MSDN中的原型:
WITH expression_name [ ( column_name [,...n] ) ]AS( CTE_query_definition ) |
按照是否递归,可以将公用表(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 处理递归查询的更多相关文章
- SqlServer共用表达式(CTE)With As
共用表表达式(CTE)可以看成是一个临时的结果集,可以再SELECT,INSERT,UPDATE,DELETE,MARGE语句中多次引用. 一好处:使用共用表表达式可以让语句更加清晰简练. 1.可以定 ...
- SQLServer中的CTE通用表表达式
开发人员正在研发的许多项目都涉及编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种情形是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Tr ...
- SQLServer中的CTE(Common Table Expression)通用表表达式使用详解
概述 我们经常会编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种方案是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Transact-S ...
- 公用表表达式 (CTE)、递归、所有子节点、sqlserver
指定临时命名的结果集,这些结果集称为公用表表达式 (CTE).公用表表达式可以包括对自身的引用.这种表达式称为递归公用表表达式. 对于递归公用表达式来说,实现原理也是相同的,同样需要在语句中定义两部分 ...
- Sql Server 公用表达式(CTE)
简介 对于select查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可续,在一个查询中引入另外的结果集都是通过视图而不是子查询来进行分解的,但是,视图是作为系统对象存在数据库中,那对于结果集 ...
- 存储过程——公用表表达式(CTE)
目录 0. 背景说明 1. 定义及语法细节 1.1 基本定义 1.2 基本语法 1.3 多个CTE同时声明 1.4 CTE嵌套使用 2. CTE递归查询 2.1 简介 2.2 准备工作 2.3 计算每 ...
- SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用
本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等 ...
- 公用表表达式CTE
公用表表达式CTE表面上和派生表非常相似,看起来只是语义上的区别.但和派生表比较起来,CTE具有几个优势:第一,如果须要在一个CTE中引用另一个CTE,不需要像派生表那样嵌套,相反,只要简单地在同一个 ...
- T-SQL 公用表表达式(CTE)
公用表表达式(CTE) 在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式( ...
随机推荐
- 201671010449 杨天超 实验十四 团队项目评审&课程学习总结
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 作业学习目标 1.掌握软件评审流程及内容 2.个人总结 实验一问题解答 实验一问题链接:https://ww ...
- Windows中的txt文件到Mac打开是乱码 解决办法
在Mac下打开“文本编辑”程序之后,选择菜单“文本编辑” -> “偏好设置”.2)在“偏好设置”中选择第二个标签页“打开和存储”,选择“纯文本文件编码”中的“打开文件”和“存储文件”修改成为“中 ...
- 负载均衡环境:nginx + 2tomcat
部署两个服务 安装两个tomcat,tomcat安装,参考:https://www.cnblogs.com/uncleyong/p/10742650.html 两个tomcat的端口要不一样(shut ...
- limits the number of elements in an IN predicate to 2100 entries.
org.hibernate.engine.jdbc.spi.SqlExceptionHelper 131 - [TxId : f68db5f5b-qmgnc^1561639897640^271530 ...
- spark基础知识一
1. spark是什么 Apache Spark™ is a unified analytics engine for large-scale data processing. spark是针对于大规 ...
- TensorFlow常用激活函数及其特点和用法(6种)详解
http://c.biancheng.net/view/1911.html 每个神经元都必须有激活函数.它们为神经元提供了模拟复杂非线性数据集所必需的非线性特性.该函数取所有输入的加权和,进而生成一个 ...
- java 压缩图片(只缩小体积,不更改图片尺寸)
1.情景展示 在调用腾讯身份证OCR接口的时候,由于要求图片大小只能限制在1MB以内,这样,就必须使用到图片压缩技术 2.代码展示 /** * 图片处理工具类 * @explain * @auth ...
- python 散点图上给每个点打标签方便看到数据
import numpy as np import matplotlib.pyplot as plt x=[2.3,4.5,3,7,6.5,4,5.3] y=[5,4,7,5,5.3,5.5,6.2] ...
- 2-3-4树(jdk8的TreeMap的红黑树)
2-3树:插入变成2个节点正常插,变成3个节点就要提升中间节点和分裂子节点,满足:要么没有子节点,要么2个子节点,要么3个子节点. 2-3-4树:插入变成2个不动,插入变成3个不动,插入变成4个提升原 ...
- sql的插入或者修改
<select id="insertOrUpdateTenantDetail" parameterType="tenantDetailDO"> IN ...