SQL遞歸

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章