Ordenar la jerarquía de resultados de la consulta recursiva en SQL 2005
-
22-08-2019 - |
Pregunta
Tengo una tabla 'tarea' con las siguientes columnas (la TaskOrder es para pedir a los niños en el ámbito de los padres, no toda la tabla):
TaskId ParentTaskId TaskName TaskOrder
Tengo esta consulta CTE para devolver todas las filas:
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
Esta consulta devuelve todas las tareas ordenadas por su nivel como era de esperar. ¿Cómo puedo cambiarlo para ordenar los resultados en su orden jerárquico que a continuación?
- Task 1 -- Task 1 Subtask 1 -- Task 1 Subtask 2 - Task 2 - Task 3
Gracias.
Editar:. La respuesta debe trabajar con un numbr ilimitado de niveles
Solución 2
resuelto el problema usando una variación de href="https://stackoverflow.com/questions/539155/ordering-recursive-query-results-in-sql-2005/539211#539211"> método de Mark , pero no voy a retener la ruta de nodo en cada nodo, para que pueda moverse más fácilmente alrededor del árbol. En su lugar he cambiado mi columna 'OrdenarPor' de un int a varchar (3) izquierda-rellenado con ceros para que pueda concatenar en un maestro 'OrdenarPor' para todas las filas devueltas.
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
Esto devuelve:
TaskId ParentTaskId OrderBy Name RowOrder --------------------------------------------------------------------------- 1 NULL 001 Task One 001 15 1 001 Task One / Task One 001001 2 NULL 002 Task Two 002 7 2 001 Task Two / Task One 002001 14 7 001 Task Two / Task One / Task One 002001001 8 2 002 Task Two / Task Two 002002 9 8 001 Task Two / Task Two / Task One 002002001 10 8 002 Task Two / Task Two / Task Two 002002002 11 8 003 Task Two / Task Two / Task Three 002002003 3 NULL 003 Task Three 003 4 NULL 004 Task Four 004 13 4 001 Task Four / Task One 004001 5 NULL 005 Task Five 005 6 NULL 006 Task Six 006 17 NULL 007 Task Seven 007 18 NULL 008 Task Eight 008 19 NULL 009 Task Nine 009 21 19 001 Task Nine / Task One 009001 20 NULL 010 Task Ten 010
no permite una jerarquía ilimitada (máximo 10 niveles / max 1000 niños por nodo padre - si es que había empezado el OrdenarPor a 0). Pero más que suficiente para mis necesidades
Otros consejos
Una forma de poder hacer esto es añadir una columna de jerarquía que tiene todos los ID anteriores en una lista:
with tasks (TaskId, ParentTaskId, [Name], TaskIdList) as
(
select parentTasks.TaskId,
parentTasks.ParentTaskId,
parentTasks.[Name],
parentTasks.TaskId
from Task parentTasks
where ParentTaskId is null
union all
select childTasks.TaskId,
childTasks.ParentTaskId,
childTasks.[Name],
tasks.TaskIdList + '.' + childTasks.TaskId
from Task childTasks
join tasks
on childTasks.ParentTaskId = tasks.TaskId
)
select TaskId, ParentTaskId, [Name] from tasks
order by TaskIdList
Tenga en cuenta que esto supone que TaskId es un identificador basado en cadena. Si no, usted debe echarlo a un varchar antes de la concatenación de él.
No es necesario todo eso unión, creo que esto debería funcionar:
select
TaskId,
ParentTaskId,
[Name],
COALESCE(ParentTaskId, TaskId) as groupField
from
task
order by
COALESCE(ParentTaskId, TaskId), ParentTaskId, TaskId
Ya que no especifican "ORDER BY", ¿cómo espera que los devuelve en ningún orden en particular (que no sea esperando que el analizador de consultas va a funcionar de alguna manera esperada?).
Si lo desea, en ParentTaskId, orden TaskId, a continuación, seleccione el TaskId como ParentTaskId y NULL como TaskId en el primer elemento de unión; entonces
ORDER BY ParentTaskId, TaskId?