利用临时表实现CTE递归查询
一、CTE递归查询简介
--CTE递归查询终止条件
在TSQL脚本中,也能实现递归查询,SQL Server提供CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询,本文详细介绍CTE递归调用的特性和使用示例,递归查询主要用于层次结构的查询,从叶级(Leaf Level)向顶层(Root Level)查询,或从顶层向叶级查询,或递归的路径(Path)。
一,递归查询原理
CTE的递归查询必须满足三个条件:初始条件,递归调用表达式,终止条件,CTE 递归查询的伪代码如下:
WITH cte_name ( column_name [,...n] )
AS
(
--Anchor member is defined
CTE_query_definition
UNION ALL
--Recursive member is defined referencing cte_name
CTE_query_definition
)
-- Statement using the CTE
SELECT * FROM cte_name
1,递归查询至少包含两个子查询:
第一个子查询称作定点(Anchor)子查询:定点查询只是一个返回有效表的查询,用于设置递归的初始值;
第二个子查询称作递归子查询:该子查询调用CTE名称,触发递归查询,实际上是递归子查询调用递归子查询;
两个子查询使用union all,求并集;
2,CTE的递归终止条件
递归查询没有显式的递归终止条件,只有当递归子查询返回空结果集(没有数据行返回)或是超出了递归次数的最大限制时,才停止递归。
默认的递归查询次数是100,可以使用查询提示(hint):MAXRECURSION 控制递归的最大次数:OPTION( MAXRECURSION 16);如果允许无限制的递归次数,使用查询提示:option(maxrecursion 0);当递归查询达到指定或默认的 MAXRECURSION 数量限制时,SQL Server将结束查询并返回错误,如下:
The statement terminated. The maximum recursion 10 has been exhausted before statement completion.
事务执行失败,该事务包含的所有操作都被回滚。在产品环境中,慎用maxrecursion 查询提示,推荐通过 where 条件限制递归的次数。
3,递归步骤
step1:定点子查询设置CTE的初始值,即CTE的初始值Set0;
递归调用的子查询过程:递归子查询调用递归子查询;
step2:递归子查询第一次调用CTE名称,CTE名称是指CTE的初始值Set0,第一次执行递归子查询之后,CTE名称是指结果集Set1;
step3:递归子查询第二次调用CTE名称,CTE名称是指Set1,第二次执行递归子查询之后,CTE名称是指结果集Set2;
step4:在第N次执行递归子查询时,CTE名称是指Set(N-1),递归子查询都引用前一个递归子查询的结果集;
Step5:如果递归子查询返回空数据行,或超出递归次数的最大限制,停止递归;
二、利用临时表实现CTE查询,主要是用来帮助理解CTE。
2.1创建测试数据
--创建表格实例
CREATE TABLE [dbo].[testtb](
[namea] [varchar](100) NULL,
[desca] [varchar](50) NULL
) ON [PRIMARY]
--插入数据
insert into testtb values('A1,A2,','AAAAA')
insert into testtb values('A3,','BBBBBB')
insert into testtb values('A5,A8,A9,','AAACCAA')
insert into testtb values('A6,A20,','AAANNNNAA')
2.2使用CTE查询
WITH testtb2 AS (
SELECT namea,desca,CHARINDEX(',',namea) STA,CHARINDEX(',',namea)-1 LENS FROM testtb
UNION ALL
SELECT namea,desca,CHARINDEX(',',namea,STA+1) STA,CHARINDEX(',',namea,STA+1)-STA-1 LENS FROM testtb2 WHERE STA<>0)
--SELECT * FROM testtb2
SELECT SUBSTRING(namea,STA-LENS,LENS) as [name],desca FROM testtb2
WHERE STA<>0
order by SUBSTRING(namea,STA-LENS,LENS)
2.3使用临时表查询
--分解查询步骤
SELECT * FROM dbo.testtb
SELECT namea,desca, CHARINDEX(',',namea) AS STA , CHARINDEX(',',namea)-1 AS Lens INTO #t1 FROM dbo.testtb
SELECT namea,desca, CHARINDEX(',',namea,STA+1) AS STA , CHARINDEX(',',namea,STA+1)-1-STA AS Lens INTO #t2 FROM #t1 WHERE STA>0
SELECT * FROM #t2
SELECT namea,desca, CHARINDEX(',',namea,STA+1) AS STA , CHARINDEX(',',namea,STA+1)-1-STA AS Lens INTO #t3 FROM #t2 WHERE STA>0
SELECT * FROM #t3
SELECT namea,desca, CHARINDEX(',',namea,STA+1) AS STA , CHARINDEX(',',namea,STA+1)-1-STA AS Lens INTO #t4 FROM #t3 WHERE STA>0
SELECT * FROM #t4
SELECT namea,desca, CHARINDEX(',',namea,STA+1) AS STA , CHARINDEX(',',namea,STA+1)-1-STA AS Lens FROM #t4 WHERE STA>0
--查询结果为空,则终止
--利用最后查询结果查询所需数据
SELECT SUBSTRING(b.namea,b.STA-LENs,b.Lens) AS namea, desca FROM (
SELECT * FROM #t1
UNION ALL SELECT * FROM #t2
UNION ALL SELECT * FROM #t3
UNION ALL SELECT * FROM #t4) b
WHERE b.STA>0.
--删除临时表
DROP TABLE #t1;DROP TABLE #t2;DROP TABLE #t3;DROP TABLE #t4
该过程未必是CTE的执行过程,但可以帮助我们理解CTE的查询。当出现错误时,可以按照分解步骤考虑出错的原因。例如无限递归错误,按照该分解步骤测试,看是否一直有查询结果,即无法终止。
碰见类似的查询时,我的思路与分步查询的方式一致,从而转换成CTE形式。
利用临时表实现CTE递归查询的更多相关文章
- SQL Server CTE 递归查询全解
在TSQL脚本中,也能实现递归查询,SQL Server提供CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询,本文详细介绍CTE递归调用的特性和使用示例 ...
- SQL Server CTE 递归查询全解 -- 转 学习
在TSQL脚本中,也能实现递归查询,SQL Server提供CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询,本文详细介绍CTE递归调用的特性和使用示例 ...
- SQL Server CTE 递归查询全解(转载)
在TSQL脚本中,也能实现递归查询,SQL Server提供CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询,本文详细介绍CTE递归调用的特性和使用示例 ...
- CTE 递归查询全解
TSQL脚本能实现递归查询,用户使用共用表表达式 CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询.本文详细介绍CTE递归调用的特性和使用示例,递归查询 ...
- SQL Server 2005中的CTE递归查询得到一棵树
感觉这个CTE递归查询蛮好用的,先举个例子: use City; go create table Tree ( ID int identity(1,1) primary key not null, N ...
- SQLServer2005中的CTE递归查询得到一棵树
最近研究了一下CTE递归查询,感觉这个CTE递归查询蛮好用的,在网上找到了一个比较好的例子,测试例子如下 use City; go create table Tree ( ID ,) primary ...
- Atitit.mysql oracle with as模式临时表模式 CTE 语句的使用,减少子查询的结构性 mssql sql server..
Atitit.mysql oracle with as模式临时表模式 CTE 语句的使用,减少子查询的结构性 mssql sql server.. 1. with ... as (...) 在mys ...
- sql server利用cte递归查询
1.数据环境准备 参考Oracle递归查询文章. 2.查询某个节点下的所有子节点 with cte(id,name,parent_id) as ( select id,name,parent_id f ...
- CTE 递归查询
使用CTE进行递归查询,能够实现对层次结构的数据的快速访问,非常有用. TSql CTE 递归原理探究 TSql 分层和递归查询 1,CTE的递归结构 递归查询的结构包括两部分:起始点和迭代公式. 使 ...
随机推荐
- 7.SSRF漏洞绕过IP限制
绕过SSRF过滤的几种方法 下文出现的192.168.0.1,10.0.0.1全部为服务器端的内网地址. 1.更改IP地址写法 一些开发者会通过对传过来的URL参数进行正则匹配的方式来过滤掉内网IP, ...
- 2. DVWA亲测命令执行漏洞
先看low级: 提示让我们输入一个IP地址来实现ping,猜测会是在系统终端中实现的, 我们正常输入127.0.0.1: 那我们就可以利用这个使用其他CMD命令 我们输入127.0.0.1& ...
- Django 的认证系统
Django自带的用户认证 auth 模块 from django.contrib import autu django.contrib.auth 中提供了许多方法, 这里主要介绍其中三个: auth ...
- 从CGI到FastCGI到PHP-FPM
从CGI到FastCGI到PHP-FPM 背景 笔者在学习这几个名词的时候,也是被百度到的相关文章迷惑.涉及到的主要名词包括 1. CGI协议 2. CGI脚本 3. PHP-CGI 4. FastC ...
- python文件名匹配
待匹配文件:#FY3D_IPMNT_GBAL_L1_20180516_0003_030KM_MS.HDF 干扰文件:#FY3D_IPMNT_GBAL_L1_20180516_0003_030KM_MS ...
- NodeJS什么都能做,为什么还要JAVA?
这张图看起来简单而且很好理解,但没尝试过,会有很多疑问. SPA模式中,后端已供了所需的数据接口,view前端已经可以控制,为什么要多加NodeJS这一层? 多加一层,性能怎么样? 多加一层,前端的工 ...
- docker常用到的一些命令
docker ps 1. docker ps -a(显示所有的容器,包括未运行的) 2.docker ps -q (只显示ip) 3. docker ps -f(根据条件过滤显示的内容) docker ...
- git教程3-分支
https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E7%AE%A1%E7%90%86 ...
- js校验金额输入
//验证非负实数,保留2位小数,不采取四舍五入,不能去掉无效零,obj是this //示例:<input type="text" onkeyup="IWS_Chec ...
- JD孔_20160901
1.买的 “[京东超市]GL格朗 耳温枪/电子体温计/温度计/耳温计EW-2” http://item.jd.com/385507.html 2.