我们在实际查询中,时常会碰到需要递归查询的例子,SQL SERVER 2005之前的版本可以用函数方法实现,SQL SERVER 2005之后可以利用CTE(公用表表达式Common Table Expression是SQL SERVER 2005版本之后引入的一个特性)的方式来查询。
--测试数据
if not object_id(N'T') is null
drop table T
Go
Create table T([id] int,[pid] int,[num] int)
Insert T
select 1,0,1 union all
select 2,1,1 union all
select 3,2,1 union all
select 4,2,1 union all
select 5,2,1 union all
select 6,3,1 union all
select 7,3,1
Go
--测试数据结束
我们想要向上累积的结果,计算每级的子集集合是多少,函数方式,新建函数:
IF OBJECT_ID('dbo.f_GetChildren') IS NOT NULL
DROP FUNCTION dbo.f_GetChildren
GO
CREATE FUNCTION f_GetChildren
(
@id INT ,
@pid INT ,
@num INT
)
RETURNS @tab TABLE
(
[id] INT ,
[pid] INT ,
[num] INT
)
AS
BEGIN
INSERT @tab
SELECT @id ,
@pid ,
@num
WHILE @@rowcount > 0
BEGIN
INSERT @tab
SELECT T.id ,
T.pid ,
T.num
FROM T
JOIN @tab t1 ON T.pid = t1.id
WHERE NOT EXISTS ( SELECT *
FROM @tab
WHERE T.id = [@tab].id )
END
RETURN
END
GO
调用:
SELECT id ,
( SELECT SUM(num)
FROM f_GetChildren(id, pid, num)
) AS sumnum
FROM T
结果:
利用CTE的方式:
;WITH cte AS (
SELECT *,id AS sumid FROM dbo.T
UNION ALL
SELECT T.*,cte.sumid FROM T JOIN cte ON T.pid=cte.ID
)
SELECT sumid,SUM(num) AS sumnum FROM cte GROUP BY sumid
结果:
以上是递归的两种基本实现方式,函数和CTE形式。