Сортировать иерархическую таблицу в SQL Сервер? - PullRequest
1 голос
/ 26 марта 2020

У меня есть таблица Адрес , и я хочу отсортировать строки как parent-1 => all-child-parent-1, parent-2 => all-child-parent-2, так on ....

Таблица адресов

ID   Caption   Parent
---------------------
1    A          NULL
2    B          NULL
3    a          1
4    b          2
5    bb         4
6    C          NULL
7    aa         3
8    c          6

NULL Родитель имеет среднее значение Root

Желаемый вывод

ID   Sort  Caption   Parent
---------------------------
1    1     A         NULL
3    2     a         1
7    3     aaa       3
2    4     B         NULL
4    5     b         2
5    6     bb        4
6    7     C         NULL
8    8     c         6

Ответы [ 4 ]

1 голос
/ 26 марта 2020

Еще одним вариантом является использование hierarcyid типа данных

Пример

Declare @YourTable Table ([ID] int,[Caption] varchar(50),[Parent] int)  Insert Into @YourTable Values 
 (1,'A',NULL)
,(2,'B',NULL)
,(3,'a',1)
,(4,'b',2)
,(5,'bb',4)
,(6,'C',NULL)
,(7,'aa',3)
,(8,'c',6)


;with cteP as (
      Select ID
            ,Parent 
            ,Caption 
            ,HierID = convert(hierarchyid,concat('/',ID,'/'))
      From   @YourTable 
      Where  Parent is null
      Union  All
      Select ID  = r.ID
            ,Parent  = r.Parent 
            ,Caption   = r.Caption
            ,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
      From   @YourTable r
      Join   cteP p on r.Parent  = p.ID)
Select Lvl   = HierID.GetLevel()
      ,ID
      ,Parent
      ,Caption 
 From cteP A
 Order By A.HierID

Возвращает

Lvl ID  Parent  Caption
1   1   NULL    A
2   3   1       a
3   7   3       aa
1   2   NULL    B
2   4   2       b
3   5   4       bb
1   6   NULL    C
2   8   6       c
0 голосов
/ 26 марта 2020

Вы можете построить путь к каждой строке, а затем использовать его для сортировки. В конструкции используется рекурсивный CTE:

with cte as (
      select id, caption, parent, convert(varchar(max), format(id, '0000')) as path, 1 as lev
      from t
      where parent is null
      union all
      select t.id, t.caption, t.parent, convert(varchar(max), concat(path, '->', format(t.id, '0000'))), lev + 1
      from cte join
           t
           on cte.id = t.parent
     )
select id, caption, parent
from cte
order by path;

Здесь - это скрипта db <>.

0 голосов
/ 26 марта 2020

Нет необходимости в рекурсии, просто используйте умную сортировку!

SELECT
  ID,
  ROW_NUMBER() over(order by Caption) as Sort,
  Caption,
  Parent
FROM Address
ORDER BY Caption, Parent

SQL Fiddle: http://sqlfiddle.com/#! 18 / bbbbe / 9

0 голосов
/ 26 марта 2020

Такая сортировка требует некоторого обхода иерархии для вычисления пути каждого узла.

Это можно сделать с помощью рекурсивного запроса:

with cte as (
    select id, caption, parent, caption addr 
    from mytable
    where parent is null
    union all
    select t.id, t.caption, t.parent, c.addr + '/' + t.caption
    from cte c
    inner join mytable t on t.parent = c.id
)
select
    id,
    row_number() over(order by addr) sort,
    caption,
    parent
from c
order by addr


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