Ordering hierarchy from recursive query results in SQL 2005

后端 未结 4 607
星月不相逢
星月不相逢 2020-12-16 06:36

I\'ve got a \'Task\' table with the following columns (the TaskOrder is for ordering the children within the scope of the parent, not the entire table):

TaskId
Pa         


        
相关标签:
4条回答
  • 2020-12-16 07:17

    You don't need all that union stuff, I think this should work:

    select
     TaskId,
     ParentTaskId,
     [Name],
     COALESCE(ParentTaskId, TaskId) as groupField
    from
     task
    order by
     COALESCE(ParentTaskId, TaskId), ParentTaskId, TaskId
    
    0 讨论(0)
  • 2020-12-16 07:26

    One way you could do this is to add a hierarchy column that has all previous IDs in a list:

    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
    

    Note that this assumes that TaskId is a string-based ID. If not, you should cast it to a varchar before concatenating it.

    0 讨论(0)
  • 2020-12-16 07:29

    Since you don't specify "ORDER BY", how do you expect that it returns them in any particular order (other than hoping the query analyzer will work in some expected fashion?).

    If you want it in ParentTaskId, TaskId order, then select the TaskId as ParentTaskId and NULL as TaskId in the first UNION element; then

    ORDER BY ParentTaskId, TaskId?

    0 讨论(0)
  • 2020-12-16 07:36

    Solved the problem using a variation of Mark's method, but I'm not retaining the node path in every node, so I can more easily move them around the tree. Instead I changed my 'OrderBy' column from an int to varchar(3) left-padded with zeros so I can concatenate them into a master 'OrderBy' for all the rows returned.

    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
    

    This returns:

    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
    

    It doesn't allow for an unlimited hierarchy (max 10 levels / max 1000 children per parent node - if I'd started the OrderBy at 0) but more than enough for my needs.

    0 讨论(0)
提交回复
热议问题