Nic*_*ick 5 recursion sql-server-2005 hierarchy common-table-expression
我有一个带有以下列的'Task'表(TaskOrder用于命令父级范围内的子级,而不是整个表):
TaskId ParentTaskId TaskName TaskOrder
我有这个CTE查询返回所有行:
with tasks (TaskId, ParentTaskId, [Name]) as
(
select parentTasks.TaskId,
parentTasks.ParentTaskId,
parentTasks.[Name]
from Task parentTasks
where ParentTaskId is null
union all
select childTasks.TaskId,
childTasks.ParentTaskId,
childTasks.[Name]
from Task childTasks
join tasks
on childTasks.ParentTaskId = tasks.TaskId
)
select * from tasks
Run Code Online (Sandbox Code Playgroud)
此查询按照您的预期返回按其级别排序的所有任务.如何更改它以将结果按以下顺序排列到其层次结构顺序中?
- Task 1 -- Task 1 Subtask 1 -- Task 1 Subtask 2 - Task 2 - Task 3
谢谢.
编辑:答案应该使用无限数量的级别.
使用马克方法的变体解决了问题,但我没有保留每个节点中的节点路径,因此我可以更轻松地在树上移动它们。相反,我将“OrderBy”列从 int 更改为左侧填充零的 varchar(3),这样我就可以将它们连接到返回的所有行的主“OrderBy”中。
with tasks (TaskId, ParentTaskId, OrderBy, [Name], RowOrder) as
(
select parentTasks.TaskId,
parentTasks.ParentTaskId,
parentTasks.OrderBy,
parentTasks.[Name],
cast(parentTasks.OrderBy as varchar(30)) 'RowOrder'
from Task parentTasks
where ParentTaskId is null
union all
select childTasks.TaskId,
childTasks.ParentTaskId,
childTasks.OrderBy,
childTasks.[Name],
cast(tasks.RowOrder + childTasks.OrderBy as varchar(30)) 'RowOrder'
from Task childTasks
join tasks
on childTasks.ParentTaskId = tasks.TaskId
)
select * from tasks order by RowOrder
Run Code Online (Sandbox Code Playgroud)
这将返回:
TaskId ParentTaskId OrderBy 名称 RowOrder -------------------------------------------------- ------------------------ 1 NULL 001 任务一 001 15 1 001 任务一 / 任务一 001001 2 NULL 002 任务二 002 7 2 001 任务二/任务一 002001 14 7 001 任务二/任务一/任务一 002001001 8 2 002 任务二 / 任务二 002002 9 8 001 任务二/任务二/任务一 002002001 10 8 002 任务二 / 任务二 / 任务二 002002002 11 8 003 任务二/任务二/任务三 002002003 3 NULL 003 任务三 003 4 NULL 004 任务四 004 13 4 001 任务四/任务一 004001 5 NULL 005 任务五 005 6 NULL 006 任务六 006 17 NULL 007 任务七 007 18 NULL 008 任务八 008 19 NULL 009 任务九 009 21 19 001 任务九/任务一 009001 20 NULL 010 任务十 010
它不允许无限的层次结构(每个父节点最多 10 个级别/最多 1000 个子节点 - 如果我从 0 开始 OrderBy),但足以满足我的需求。