родительское дочернее дерево sql с порядком сортировки - PullRequest
1 голос
/ 13 марта 2012

Предполагая, что эта таблица

ParentId    ChildId    SortOrder
---------------------------------
0           1          0
1           2          1
2           3          1
2           4          2
2           6          3
1           7          2
1           9          3
9           10         1
9           12         2

как бы я написал простой CTE (или другой тип запроса), который бы возвращал им родительские / дочерние отношения на любом уровне, но сохраняя порядок сортировки для всех дочернихэлементы ниже родительского.

В основном это будет простое древовидное представление с подпунктами, упорядоченными по определенному порядку сортировки.

sql server 2008 является обновлением db

: могут быть бесконечные родительские / дочерние уровни - я пробовал несколько примеров из других вопросов / ответов по стеку, но ни один не включал сортировщик на дочернем уровне.

пример результата должен быть таким:

parent (sort 0)
    child (sort 1)
    child (sort 2)
    child (sort 3)
        child-child (sort 1)
    child (sort 4)
        child-child (sort 1)
        child-child (sort 2)

и т. Д.

надеюсь, что это имеет смысл - возможно, я смотрю на это неправильно, и такой результат лучше бытьпостроен в середине уровня?

в любом случае, любая обратная связь с благодарностью

Ответы [ 2 ]

7 голосов
/ 13 марта 2012

Рекурсивный CTE со специальным переопределением сортировки. Обратите внимание на переопределение сортировки в потомках 2 (я немного изменил исходную таблицу, чтобы проверить эту способность)

declare @relations table(ParentID int, ChildID int, SortOrder int, treeID int);

insert into @relations values
(0,1,0,0), (1,2,1,0), (2,3,2,0), (2,4,1,0), (2,6,3,0), (1,7,2,0), (1,9,3,0), (9,10,1,0), (9,12,2,0) --tree 0
, (0,1,0,1), (1,2,1,1), (2,3,2,1), (2,4,1,1), (2,6,3,1), (1,7,2,1), (1,9,3,1), (9,10,1,1), (9,12,2,1) --tree 1

; with cte(ParentId,ChildId,SortOrder,depth,agg,treeID) as (
    select null,ParentId,SortOrder,0
    , right('0000000'+CAST(treeID as varchar(max)),7)
        +right('0000000'+CAST(SortOrder as varchar(max)),7)
    , treeID
    from @relations where ParentId=0
    union all
    select cte.ChildId,r.ChildId,r.SortOrder,cte.depth+1
    , cte.agg
        +right('0000000'+CAST(r.treeID as varchar(max)),7)
        +right('0000000'+CAST(r.SortOrder as varchar(max)),7)
        +right('0000000'+CAST(r.ChildId as varchar(max)),7)
    , r.treeID
    from cte
    inner join @relations r on r.ParentID=cte.ChildId
    where cte.depth<32767
    and r.treeID=cte.treeID
)
select
tree=case depth when 1 then cast(ParentID as varchar(30))+' (sort '+cast(SortOrder as varchar(30))+')'
    else REPLICATE(CHAR(9),depth-1)
        + cast(ChildId as varchar(30))+' (sort '+cast(SortOrder as varchar(30))+')'
    end
from cte
where depth>0
order by agg
option (maxrecursion 32767);

Результат:

tree
--------------------------------------------------
0 (sort 0)
    2 (sort 1)
        4 (sort 1)
        3 (sort 2)
        6 (sort 3)
    7 (sort 2)
    9 (sort 3)
        10 (sort 1)
        12 (sort 2)
0 (sort 0)
    2 (sort 1)
        4 (sort 1)
        3 (sort 2)
        6 (sort 3)
    7 (sort 2)
    9 (sort 3)
        10 (sort 1)
        12 (sort 2)
0 голосов
/ 13 марта 2012

звучит почти так же, как я ответил здесь Вам придется немного изменить порядок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...