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

War es hilfreich?

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?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top