Ordinazione gerarchia dai risultati di query ricorsive in SQL 2005
-
22-08-2019 - |
Domanda
Ho una tabella 'Task' con le seguenti colonne (il TaskOrder è per ordinare i bambini nell'ambito di applicazione del genitore, non l'intera tabella):
TaskId ParentTaskId TaskName TaskOrder
Ho questa query CTE di restituire tutte le righe:
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
Questa query restituisce tutte le attività ordinate dal loro livello come ci si aspetterebbe. Come posso cambiarlo per ordinare i risultati in loro ordine gerarchico, come di seguito?
- Task 1 -- Task 1 Subtask 1 -- Task 1 Subtask 2 - Task 2 - Task 3
Grazie.
Modifica:. La risposta dovrebbe funzionare con una numbr illimitato di livelli
Soluzione 2
risolto il problema utilizzando una variante del metodo href="https://stackoverflow.com/questions/539155/ordering-recursive-query-results-in-sql-2005/539211#539211"> , ma non sto mantenendo il percorso del nodo in ogni nodo, in modo da poter più facilmente spostarli intorno all'albero. Invece ho cambiato la mia colonna 'OrderBy' da un int a varchar (3) a sinistra imbottita con zeri modo che io possa concatenare in un master 'OrderBy' per tutte le righe restituite.
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
Questa operazione riporta:
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
E 'non consente una gerarchia senza limiti (max 10 livelli / max 1000 bambini per nodo padre - se avessi iniziato l'OrderBy a 0). Ma più che sufficiente per le mie esigenze
Altri suggerimenti
Un modo che si possa fare è quello di aggiungere una colonna gerarchia che ha tutti gli ID precedenti in un elenco:
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
Si noti che questo presuppone che TaskId è un ID di stringa-based. In caso contrario, si dovrebbe lanciare ad un varchar prima di concatenazione di esso.
Non hai bisogno di tutta quella roba unione, credo che questo dovrebbe funzionare:
select
TaskId,
ParentTaskId,
[Name],
COALESCE(ParentTaskId, TaskId) as groupField
from
task
order by
COALESCE(ParentTaskId, TaskId), ParentTaskId, TaskId
Dal momento che non è necessario specificare "ORDER BY", come si aspetta che li restituisce in un ordine particolare (diverso sperando che il Query Analyzer funzionerà in qualche modo previsto?).
Se si desidera in ParentTaskId, ordine TaskId, quindi selezionare il TaskId come ParentTaskId e NULL come TaskId nel primo elemento UNION; poi
ORDER BY ParentTaskId, TaskId?