sql Обход родителя-потомка

Я имею дело с некоторыми иерархическими данными в следующем виде:

Level      Parent    PrimaryKey    LevelDepth    RevenuePct
Total       NULL     2786f8161           0           100
US          Total    33f254b0f           1           60
UK          Total    462adbba            1           25
Asia        Total    5322678b3           1           15
Mobile       US      75b72bdf1           2           10
Laptop       US      813784df5           2           10
PC           US      9550f97c            2           15
Consulting   US      a44ae3ef8           2           25
Mobile       UK      ace663d07           2           10
Laptop       UK      b373e61c            2           8
PC           UK      ca590ef44           2           7
Mobile      Asia     d136f267e           2           15

и я хочу, чтобы он отображался в следующем виде:

Breakup                      Revenue [%]
Total                           100
    US                           60
            Mobile               10
            Laptop               10
            PC                   15
            Consulting           25
    UK                           25
            Mobile               10
            Laptop                8
            PC                    7
    Asia                         15
            Mobile               15

Актуальная задача имеет 6-7 уровень вложенности.

Я относительно новичок в этой области и пытаюсь использовать CTE, но у меня проблема с условием присоединения, поскольку дочерние записи повторяются в разных родителях (т.е. у меня есть категория мобильных устройств для США, Великобритании и т. д.).


person user1512829    schedule 08.08.2012    source источник


Ответы (1)


Вот один из способов сделать это. Столбец Path используется для сортировки - вам, вероятно, следует вместо \ объединить фиксированную ширину level для создания пути. Запрос работает, рекурсивно вызывая часть cte до тех пор, пока ни одна строка не удовлетворяет условию соединения между первой частью cte (выраженной как cte во второй части после объединения всех) и таблицей1.

; with cte as (
  select level, parent, revenuepct, leveldepth, cast (level as varchar(1000)) Path
    from table1
   where parent is null
  union all
  select a.level, a.parent, a.revenuepct, a.leveldepth, cast (path + '\' + a.level as varchar(1000))
    from table1 a
   inner join cte
      on a.parent = cte.level
)
-- Simple indentation
select space(leveldepth * 4) + level as Breakup, 
       revenuepct as [revenue %]
  from cte
 order by path
-- Max recursive calls, 0 = unlimited
option (maxrecursion 10)

Вот Sql Fiddle с примером.

А вот ссылка на статью о рекурсивном cte< /а>

person Nikola Markovinović    schedule 08.08.2012
comment
..Благодарю за ваш ответ. Я придумал что-то похожее, но запрос не будет выполнен, если мы перейдем на другой уровень вниз, например, если у нас есть дочерние объекты ModelA, ModelB и ModelC для мобильных телефонов в США и Великобритании. - person user1512829; 08.08.2012
comment
@user1512829 user1512829 Вам нужно добавить опцию (maxrecursion 0), пожалуйста, проверьте мой обновленный ответ. - person Nikola Markovinović; 08.08.2012