-- with一个临时表(括号中是你要查询的列名)
with temp(ID,PID,Name,te,curLevel)
as
(
--1:初始查询(这里的ParentAddressBookId is null 在我的数据中是最底层的根节点)
select AddressBookId,ParentAddressBookId,AddressBookName,CAST(AddressBookName AS nvarchar(MAX)) AS name,1 as level from dbo.PersonalAddressBook
where ParentAddressBookId is null
union all
--2:递归条件
select a.AddressBookId,a.ParentAddressBookId,a.AddressBookName, cast(replicate(' ',len(b.te))+'|_'+a.AddressBookName as nvarchar(MAX)) as TE,b.curLevel+1
from PersonalAddressBook a --3:这里的临时表和原始数据表都必须使用别名,不然递归的时候不知道查询的是那个表的列
inner join
temp b
on ( a.ParentAddressBookId=b.ID) --这个关联关系很重要,一定要理解一下谁是谁的父节点
)
select * from temp --order by ID --4:递归完成后 一定不要少了这句查询语句 否则会报错
现在的问题是,排序会乱,。。。。。
然后找到一个周大神的解决方案:
--PersonalAddressBook 表名
--OrderNumber 表内排序,没有 使用 select 1 取代
--AddressBookId ID
--ParentAddressBookId 父ID
--解决树层次多,层次内个数多的问题。
--理论上支持几百层,层内数万以上的结构。
--16W行数结构1分钟多,3000行数就 1秒,4000行1秒,5000行3秒 7000行 5秒左右 (数据库生成树结构时间)
--进行树形结构排序
--试用自行替换字段
WITH StepCTE1
AS
(--(这里lev 和 表里面treelevel无关,重新设定层级了。)
select AddressBookId,AddressBookName,CAST(AddressBookName AS nvarchar(MAX)) AS name,ParentAddressBookId,1 as Lev, convert(int,ROW_NUMBER() OVER(ORDER BY (OrderNumber))) as t1,
0 as t2,0 as t3,0 as t4, 0 as t5, 0 as t6, 0 as t7, 0 as t8, 0 as t9, 0 as t10
from PersonalAddressBook where ParentAddressBookId is null --这里是入口层 如果有限制,这里增加其他 条件
UNION ALL
select t.AddressBookId,t.AddressBookName,cast(replicate(' ',CTE.Lev*4)+'|_'+t.AddressBookName as nvarchar(MAX)) as name,t.ParentAddressBookId ,CTE.Lev + 1,
CTE.t1 as t1,
case when CTE.[Lev] = 1 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t2 end as t2,
case when CTE.[Lev] = 2 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t3 end as t3,
case when CTE.[Lev] = 3 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t4 end as t4,
case when CTE.[Lev] = 4 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t5 end as t5,
case when CTE.[Lev] = 5 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t6 end as t6,
case when CTE.[Lev] = 6 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t7 end as t7,
case when CTE.[Lev] = 7 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t8 end as t8,
case when CTE.[Lev] = 8 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t9 end as t9,
case when CTE.[Lev] = 9 then convert(int,ROW_NUMBER() OVER(ORDER BY (t.OrderNumber)))
else CTE.t10 end as t10
from PersonalAddressBook t INNER JOIN StepCTE1 CTE ON T.ParentAddressBookId = CTE.AddressBookId
--如果有限制,这里增加 where 条件
)
SELECT
AddressBookId, ParentAddressBookId, AddressBookName,name, Lev, t1,t2,t3,t4,t5,t6,t7,t8,t9,t10
FROM
StepCTE1
ORDER BY
t1,t2,t3,t4,t5,t6,t7,t8,t9,t10
但是好像排序写死了,好多t0,t1,t2.......难道有几层要写几层,容我再找找资料去。。。大神应该还有别的解决办法