Bestell Hierarchie von rekursiven Abfrageergebnisse in SQL 2005
-
22-08-2019 - |
Frage
Ich habe eine ‚Aufgabe‘ Tabelle mit den folgenden Spalten bekommt (die Taskorder ist es, die Kinder im Rahmen der Mutter für die Bestellung, nicht die gesamte Tabelle):
TaskId ParentTaskId TaskName TaskOrder
Ich habe diese CTE-Abfrage hat alle Zeilen zurückgeben:
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
Diese Abfrage gibt alle von ihrem Niveau bestellt Aufgaben wie man erwarten würde. Wie kann ich es ändern, um die Ergebnisse in ihre Hierarchie, um wie unten zu bestellen?
- Task 1 -- Task 1 Subtask 1 -- Task 1 Subtask 2 - Task 2 - Task 3
Danke.
Edit:. Die Antwort sollte mit einer unbegrenzten numbr Ebenen arbeiten
Lösung 2
Das Problem einer Variation von Mark Methode mit , aber ich bin Beibehaltung des Knoten Pfad nicht in jedem Knoten, also kann ich sich leichter um den Baum zu bewegen. Stattdessen änderte ich meine ‚OrderBy‘ Spalte von einem int varchar (3) links mit Nullen aufgefüllt, damit ich sie in einen Master ‚OrderBy‘ für alle Zeilen zurück verketten kann.
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
Das gibt:
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
Es erlaubt nicht für eine unbegrenzte Hierarchie (max 10 Stufen / max 1000 Kinder pro Elternknoten - wenn ich die OrderBy bei 0 begonnen hatte). Aber mehr als genug für meine Bedürfnisse
Andere Tipps
Eine Möglichkeit, dies tun könnte, ist eine Hierarchiespalte hinzuzufügen, die alle vorherigen IDs in einer Liste:
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
Beachten Sie, dass dies setzt voraus, dass TaskId ist eine String-basierte ID. Wenn nicht, sollten Sie es zu einem varchar werfen, bevor es verketten.
Sie brauchen nicht, dass alle Vereinigung Zeug, ich denke, das sollte funktionieren:
select
TaskId,
ParentTaskId,
[Name],
COALESCE(ParentTaskId, TaskId) as groupField
from
task
order by
COALESCE(ParentTaskId, TaskId), ParentTaskId, TaskId
Da Sie angeben „ORDER BY“ nicht, wie Sie erwarten, dass es sie in einer bestimmten Reihenfolge zurückgibt (andere als die Abfrage-Analysator der Hoffnung wird in einigen erwarteten Art und Weise arbeiten?).
Wenn Sie es in ParentTaskId, TaskId bestellen möchten, dann wählen Sie die TaskId als ParentTaskId und NULL als TaskId im ersten UNION Element; dann
ORDER BY ParentTaskId, TaskId?