在 SQL 服务器中对分层 table 进行排序?

Sort Hierarchical table in SQL Server?

我有一个 table Address 我想对行进行排序 parent-1 => all-child-parent-1, parent -2 => all-child-parent-2 依此类推....

地址Table

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 Parent is is mean 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

这种排序需要以某种方式遍历层次结构来计算每个节点的路径。

您可以使用递归查询来执行此操作:

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


您可以构造每一行的路径,然后使用它进行排序。该构造使用了递归 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;

Here 是一个 db<>fiddle.

不需要递归,只需使用一些巧妙的排序!

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

还有一种选择是使用 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

Returns

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