公用表表达式 (CTE) 具备一个重要的优势,那就是可以引用其自身,从而建立递归 CTE。递归 CTE 是一个重复执行初始 CTE 以返回数据子集直到获取完整结果集的公用表表达式。 当某个查询引用递归 CTE 时,它即被称为递归查询。递归查询一般用于返回分层数据,例如:显示某个组织图中的雇员或物料清单方案(其中父级产品有一个或多个组件,而那些组件可能还有子组件,或者是其余父级产品的组件)中的数据。 递归 CTE 能够极大地简化在 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句中运行递归查询所需的代码。在 SQL Server 的早期版本中,递归查询一般须要使用临时表、游标和逻辑来控制递归步骤流。 递归查询 **************建表******************** REATE TABLE [dbo].[Co_ItemNameSet]( [ItemId] [int] NULL, [ParentItemId] [int] NULL, [ItemName] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL ) ON [PRIMARY] *************插入数据*********************** --给表插入数据 insert into dbo.Co_ItemNameSet values(2,0,'管理费用') insert into dbo.Co_ItemNameSet values(3,0,'销售费用') insert into dbo.Co_ItemNameSet values(4,0,'财务费用') insert into dbo.Co_ItemNameSet values(5,0,'生产成本') insert into dbo.Co_ItemNameSet values(35,5,'材料') insert into dbo.Co_ItemNameSet values(36,5,'人工') insert into dbo.Co_ItemNameSet values(37,5,'制造费用') insert into dbo.Co_ItemNameSet values(38,35,'原材料') insert into dbo.Co_ItemNameSet values(39,35,'主要材料') insert into dbo.Co_ItemNameSet values(40,35,'间辅材料') insert into dbo.Co_ItemNameSet values(41,36,'工资') insert into dbo.Co_ItemNameSet values(42,36,'福利') insert into dbo.Co_ItemNameSet values(43,2,'管理费用子项') insert into dbo.Co_ItemNameSet values(113,43,'管理费用子项的子项') **********************用CTE递归操做的sql语句以下:**************** DECLARE @i INT SELECT @i=2; WITH Co_ItemNameSet_CTE(ItemId,ParentItemId,ItemName,[Level]) AS ( SELECT ItemId,ParentItemId,ItemName,1 AS [Level] FROM Co_ItemNameSet WHERE itemid=@i UNION ALL SELECT c.ItemId,c.ParentItemId,c.ItemName,[Level] + 1 FROM Co_ItemNameSet c INNER JOIN Co_ItemNameSet_CTE ct ON c.ParentItemId=ct.ItemId ) SELECT * FROM Co_ItemNameSet_CTE 主要分析一下用CTE的递归操做: 递归 CTE 由下列三个元素组成: 例程的调用。 递归 CTE 的第一个调用包括一个或多个由 UNION ALL、UNION、EXCEPT 或 INTERSECT 运算符联接的 CTE_query_definitions。因为这些查询定义造成了 CTE 结构的基准结果集,因此它们被称为“定位点成员”。 CTE_query_definitions 被视为定位点成员,除非它们引用了 CTE 自己。全部定位点成员查询定义必须放置在第一个递归成员定义以前,并且必须使用 UNION ALL 运算符联接最后一个定位点成员和第一个递归成员。 例程的递归调用。 递归调用包括一个或多个由引用 CTE 自己的 UNION ALL 运算符联接的 CTE_query_definitions(就是as里的语句块)。这些查询定义被称为“递归成员”。 终止检查。 终止检查是隐式的;当上一个调用中未返回行时,递归将中止。 递归 CTE 结构必须至少包含一个定位点成员和一个递归成员。如下伪代码显示了包含一个定位点成员和一个递归成员的简单递归 CTE 的组件。 WITH cte_name ( column_name [,...n] ) AS ( CTE_query_definition --定位点成员 UNION ALL CTE_query_definition --递归成员. ) 如今让咱们看一下递归执行过程: 将 CTE 表达式拆分为定位点成员和递归成员。 运行定位点成员,建立第一个调用或基准结果集 (T0)。 运行递归成员,将 Ti 做为输入,将 Ti+1 做为输出。 重复步骤 3,直到返回空集。 返回结果集。这是对 T0 到 Tn 执行 UNION ALL 的结果。