T-SQL实现父子层级数据按父到子顺序排序的技术问询
解决层级数据的递归查询与排序问题
你当前的CTE递归逻辑搞反了方向,而且缺少层级标识和用于排序的路径字段,所以没法得到父子层级紧跟的排序结果。咱们调整一下递归CTE的写法,从根节点(Parent为NULL的节点)开始向下遍历,同时生成Level字段和排序用的路径,就能实现你想要的效果。
正确的递归查询代码
;WITH cte AS ( -- 锚点成员:选取所有根节点,设置初始层级为3(匹配你示例中的根节点层级) SELECT Child, Parent, Position, Level = 3, -- 生成排序路径,用根节点的Position作为基础 SortPath = CAST(Position AS VARCHAR(MAX)) FROM groups WHERE Parent IS NULL UNION ALL -- 递归成员:遍历子节点,层级递减,拼接排序路径 SELECT t.Child, t.Parent, t.Position, Level = cte.Level - 1, -- 把当前子节点的Position拼接到父节点路径后,保证层级排序正确 SortPath = cte.SortPath + '.' + CAST(t.Position AS VARCHAR(MAX)) FROM groups t JOIN cte ON t.Parent = cte.Child ) -- 按排序路径确保父节点在前,相同父节点下按Position排序 SELECT Level, Child, Parent, Position FROM cte ORDER BY SortPath, Position;
代码逻辑说明
- 锚点成员:先筛选出所有顶级节点(
Parent IS NULL),设置初始Level为3,同时创建SortPath字段——用顶级节点的Position作为初始路径,比如根节点A的SortPath是'1',E是'2',F是'3'。 - 递归成员:将子节点与父节点关联(
t.Parent = cte.Child),层级比父节点减1,并且把当前子节点的Position拼接到父节点的SortPath后面,比如B是A的子节点,SortPath就变成'1.1',C是B的子节点,SortPath是'1.1.1'。 - 排序规则:通过
SortPath保证整个层级的顺序(父节点在前,子节点紧跟),同时相同父节点下的子节点按Position升序排列,完全匹配你期望的输出。
最终查询结果
| Level | Child | Parent | Position |
|---|---|---|---|
| 3 | A | NULL | 1 |
| 2 | B | A | 1 |
| 1 | C | B | 1 |
| 1 | D | B | 2 |
| 3 | E | NULL | 2 |
| 3 | F | NULL | 3 |
| 2 | G | F | 1 |
| 1 | H | G | 1 |
| 1 | I | G | 2 |
| 2 | J | F | 2 |
| 1 | K | J | 1 |
| 1 | L | J | 2 |
内容的提问来源于stack exchange,提问作者user2463808
相关产品推荐
相关产品推荐

