SQL查询二叉树

--1.建表
CREATE TABLE #T
(
 id INT,
 [name] VARCHAR(10),
 [for] INT,
 [left] INT,
 [right] INT
)
--2.插入数据 
INSERT INTO #T VALUES(1, '小小', 0, 3, 2)
INSERT INTO #T VALUES(4, '笑笑', 2, 8, 9)
INSERT INTO #T VALUES(5, '琦琦', 2, 13, 0)
INSERT INTO #T VALUES(2, '琪琪', 1, 5, 4)
INSERT INTO #T VALUES(3, '晓晓', 1, 6, 7)
INSERT INTO #T VALUES(6, '兵兵', 3, 10, 11)
INSERT INTO #T VALUES(7, '冰冰', 5, 0, 12)
INSERT INTO #T VALUES(8, '公主', 4, 0, 0)
INSERT INTO #T VALUES(9, '筱筱', 4, 0, 0)
INSERT INTO #T VALUES(10, '姗姗',  6, 0, 0)
INSERT INTO #T VALUES(11, '珊珊',  6, 0, 0)
INSERT INTO #T VALUES(12, '微微',  7, 0, 0) 
INSERT INTO #T VALUES(13, '薇薇',  5, 0, 0)

DECLARE @M INT 
DECLARE @W NVARCHAR(max)=''
DECLARE @S NVARCHAR(max)=''
DECLARE @Sql NVARCHAR(max)=''
--3.计算深度
;
WITH CT
AS
(
SELECT *,1 AS i FROM #T WHERE [for]=0
UNION ALL
SELECT #T.id,#T.name,#T.[for],#T.[left],#T.[right],i+1 FROM CT INNER JOIN #T ON CT.[left]=#T.id
UNION ALL
SELECT #T.id,#T.name,#T.[for],#T.[left],#T.[right],i+1 FROM CT INNER JOIN #T ON CT.[right]=#T.id
)
SELECT @M=MAX(I) FROM CT
--4.得到列数
;WITH CT
AS
(
 SELECT POWER(2,@M)-1 AS A
 UNION ALL
 SELECT A-1 FROM CT WHERE A>1
)
SELECT @W=@W+','+QUOTENAME(A),@S=@S+',isnull('+QUOTENAME(A)+','''') as '+QUOTENAME(A) FROM CT ORDER BY CT.A
OPTION(MAXRECURSION 32767)
SET @W=STUFF(@W,1,1,'')
--5.递归+行列转换 
SET @Sql='
WITH CT
AS
(
SELECT *,1 AS i, POWER(2,@M)/2 AS j FROM #T WHERE [for]=0
UNION ALL
SELECT #T.id,#T.name,#T.[for],#T.[left],#T.[right],i+1,j-POWER(2,@M-i-1) FROM CT INNER JOIN #T ON CT.[left]=#T.id
UNION ALL
SELECT #T.id,#T.name,#T.[for],#T.[left],#T.[right],i+1,j+POWER(2,@M-i-1) FROM CT INNER JOIN #T ON CT.[right]=#T.id
)
SELECT i as id'+@S+' FROM  
(
SELECT * FROM 
(
SELECT name,i,j FROM CT 
) A
PIVOT
(
 MAX(name)
 FOR j IN
 ('+@W+') 
)P
)Q'
EXEC  sp_executesql @Sql,N'@M int',@M
DROP TABLE #T

猜你喜欢

转载自blog.csdn.net/mxbing1984/article/details/82499441