TSQL脚本能实现递归查询,用户使用共用表表达式 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:如果递归子查询返回空数据行,或超出递归次数的最大限制,停止递归;

二,递归查询示例(员工职称)

1,创建测试数据

ManagerID是UserID的父节点,这是一个非常简单的层次结构模型。

use tempdb
go 

create table dbo.dt_user
(
    UserID int,
    ManagerID int,
    Name Nvarchar(10)
)

insert into dbo.dt_user
select 1,-1,N'Boss'
union all
select 11,1,N'A1'
union all
select 12,1,N'A2'
union all
select 13,1,N'A3'
union all
select 111,11,N'B1'
union all
select 112,11,N'B2'
union all
select 121,12,N'C1'
View Code

相关文章:

  • 2021-05-31
  • 2021-07-22
  • 2022-12-23
  • 2022-12-23
  • 2022-01-08
猜你喜欢
  • 2022-02-19
  • 2022-12-23
  • 2021-11-11
  • 2021-06-01
  • 2021-08-05
  • 2021-07-18
相关资源
相似解决方案