如何用T-SQL实现带兄弟排序的父子表深度优先遍历生成序列器?
可行,用SQL Server 2016递归CTE即可实现
核心思路
利用递归CTE遍历邻接表,在递归过程中维护深度优先排序路径(结合父节点的排序路径与当前节点的Sorter值),最终通过ROW_NUMBER()按该路径生成序列编号,确保序列随Sorter变动动态更新。
假设表结构
假设你的树节点表名为TreeNodes,字段定义如下:
CREATE TABLE TreeNodes ( NodeID INT PRIMARY KEY, ParentID INT NULL, -- 根节点ParentID为NULL或0,根据实际场景调整 Sorter INT NOT NULL, -- 控制兄弟节点顺序的字段 NodeName NVARCHAR(100) -- 可选,节点名称字段 );
实现代码
WITH RecursiveTree AS ( -- 锚点成员:获取所有根节点,初始化排序路径、层级 SELECT NodeID, ParentID, Sorter, NodeName, 1 AS Level, -- 格式化Sorter为固定长度字符串,避免数字排序逻辑错误(比如10排在2前面) FORMAT(Sorter, 'D10') + '.' + CAST(NodeID AS VARCHAR(10)) AS SortPath FROM TreeNodes WHERE ParentID IS NULL -- 根节点判断条件,需和实际表结构匹配 UNION ALL -- 递归成员:关联子节点,拼接父节点的排序路径 SELECT child.NodeID, child.ParentID, child.Sorter, child.NodeName, parent.Level + 1 AS Level, parent.SortPath + '.' + FORMAT(child.Sorter, 'D10') + '.' + CAST(child.NodeID AS VARCHAR(10)) AS SortPath FROM TreeNodes child INNER JOIN RecursiveTree parent ON child.ParentID = parent.NodeID ) -- 生成最终序列器:按SortPath排序后生成连续编号 SELECT NodeID, NodeName, Level, Sorter, ROW_NUMBER() OVER (ORDER BY SortPath) AS SequenceNumber FROM RecursiveTree ORDER BY SequenceNumber;
关键说明
- SortPath的作用:通过拼接父节点的排序路径与当前节点的格式化Sorter,确保遍历顺序严格遵循深度优先+Sorter排序。用
FORMAT(Sorter, 'D10')将Sorter转为10位固定长度字符串(补前导零),避免数值类型Sorter排序时出现逻辑错误。 - 动态适配变动:当节点增删、Sorter调整后,重新执行该查询即可得到最新的序列编号,无需额外维护逻辑。
- 适配不同Sorter类型:如果Sorter是字符串类型,直接拼接即可;如果是其他数值类型,调整格式化规则(比如
FORMAT(Sorter, 'D8'))即可。
内容的提问来源于stack exchange,提问作者Atrus2711
相关产品推荐
相关产品推荐

