欢迎进入Windows社区论坛,与300万技术人员互动交流 >>进入 在操作树形数据结构的时候,我们可能会遇到这样的需求:要求把一棵树所有节点排序,比如,在使用easyui树形菜单时,我们通常会在后台做好菜单的排序处理,因为easyui是不会排序的。当然,我们有专
欢迎进入Windows社区论坛,与300万技术人员互动交流 >>进入
在操作树形数据结构的时候,我们可能会遇到这样的需求:要求把一棵树所有节点排序,比如,在使用easyui树形菜单时,我们通常会在后台做好菜单的排序处理,因为easyui是不会排序的。当然,我们有专门的字段OrderNum表示一个节点在同级节点的顺序。
排序的规则是:
一、同级节点根据其OrderNum大小先后排序;
二、不同级级节点根据其同级祖先节点OrderNum大小先后排序;
测试数据如下:
SELECT * INTO #Test
FROM (
SELECT 1 AS ID--菜单ID
,'菜单' AS Name, --菜单名
0 AS ParentId, --父菜单Id
1 AS OrderNum --同级顺序号
UNION ALL SELECT 2,'文件' AS Name,1 AS ParentId,1
UNION ALL SELECT 3,'编辑' AS Name,1 AS ParentId,2
UNION ALL SELECT 4,'工具' AS Name,1 AS ParentId,3
UNION ALL SELECT 5,'打开' AS Name,2 AS ParentId,1
UNION ALL SELECT 6,'关闭' AS Name,2 AS ParentId,2
UNION ALL SELECT 7,'新建' AS Name,2 AS ParentId,3
UNION ALL SELECT 8,'撤销' AS Name,3 AS ParentId,3
UNION ALL SELECT 9,'复制' AS Name,3 AS ParentId,2
UNION ALL SELECT 10,'全选' AS Name,3 AS ParentId,1
UNION ALL SELECT 11,'选项' AS Name,4 AS ParentId,1) AS tt
我们构建了一颗树形菜单,现在我们要对这颗树进行排序,我们的目的是使所有同级节点按OrderNum排序,目标结果如下:
解决方案如下:
WITH temp as
(
SELECT ID, Name, ParentId,CAST(CHAR(OrderNum+65) as varchar(50)) AS TOrder
From #Test
WHERE ParentId = 0
UNION ALL
SELECT #Test.ID, #Test.Name, #Test.ParentId, CAST(temp.TOrder+CHAR(#Test.OrderNum+65)AS varchar(50))
FROM temp
INNER JOIN #Test
ON temp.ID = #Test.ParentId
)
SELECT *
FROM temp
ORDER BY TOrder
代码其实挺简单的,几点说明:
一、因为树可能有很多层,涉及不同层节点的OrderNum比较,因此递归是必须的,代码的思想在于根据其在树中的路径来排序。
二、之前想过用整树来表示某个节点在树中的路径,那样,当同级节点超过9个会有问题,用Acsii转字符串完美解决问题。