1.表結構:
表名 tbName
字段:編號 id pk;名稱 name;父級編號 ParentID ;
2.數據:
001 一級001 null
002 一級002 null
001001 一級子級01 001
001002 一級子級02 001
001003 一級子級03 001
002001 二級子級01 002
002002 二級子級02 002
002003 二級子級03 002
00200101 二級子級01子級01 002001
3.SQL 獲取某個節點下的所有子節點CREATE PROC getAllChil(@pid int)
AS
BEGIN
WITH cteTree
AS (SELECT *
FROM tbName
WHERE Id = @pid --第一個查詢作爲遞歸的基點(錨點)
UNION ALL
SELECT tbName.* --第二個查詢作爲遞歸成員, 下屬成員的結果爲空時,此遞歸結束。
FROM
cteTree INNER JOIN tbName ON cteTree.Id =tbName.pid)
SELECT *
FROM cteTree
END
4.結果:exec getAllChil @pid='002'
002 一級002 null
002001 二級子級01 002
002002 二級子級02 002
002003 二級子級03 002
00200101 二級子級01子級01 002001
題外話:其實我們可以在添加一個字段把所有該節點的父級ID都加上。例如這樣:
001 一級001 null null
002 一級002 null null
001001 一級子級01 001 001;
001002 一級子級02 001 001;
001003 一級子級03 001 001;
002001 二級子級01 002 002;
002002 二級子級02 002 002;
002003 二級子級03 002 002;
00200101 二級子級01子級01 002001 002;002001;
00200102 二級子級01子級02
002001 002;002001;
0020010101 二級子級01子級01子級01
00200101 002;002001;00200101;
這樣,如果要查詢002所有的子級,直接like '002;%'即可。
遞歸的存儲過程
/*----------------------------------------------------------*//* [PC1recursion] */
/*----------------------------------------------------------*/
IF EXISTS ( SELECT 1 FROM sys.objects o WHERE object_id = object_id( N'[PC1recursion]' ) AND OBJECTPROPERTY( object_id, N'IsProcedure') = 1 )
DROP PROCEDURE [PC1recursion]
GO
CREATE PROC [PC1recursion]
(
@tbname VARCHAR(36) = '', --表明
@id varchar(50)='',--id名稱
@idValue varchar(36)='',--id值
@pid varchar(1000) = ''--父級ID名稱
)
AS
/*
功能:根據表,查詢該表嚇所有本級以及所有子級數據
參數:
返回:遞歸返回所有數據
編寫:ljr 2017-07-8
測試:
*/
BEGIN
declare @sql varchar(max)
set @sql='WITH cteTree
AS (SELECT *
FROM '+@tbname+'
WHERE '+@id+'='''+@idValue+''' --第一個查詢作爲遞歸的基點(錨點)
UNION ALL
SELECT '+@tbname+'.* --第二個查詢作爲遞歸成員, 下屬成員的結果爲空時,此遞歸結束。
FROM
cteTree INNER JOIN '+@tbname+' ON cteTree.'+@id+' ='+@tbname+'.'+@pid+')
select * from cteTree'
print @sql
exec (@sql)
END
GO