1
votes

Trier la table hiérarchique dans SQL Server?

J'ai une table Adresse et je souhaite trier les lignes comme parent-1 => all-child-parent-1, parent-2 => all-child-parent-2 ainsi de suite ....

Table d'adresses

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

NULL Parent est est une racine moyenne

Sortie souhaitée

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


0 commentaires

4 Réponses :


0
votes

Un tel tri nécessite en quelque sorte de parcourir la hiérarchie pour calculer le chemin de chaque nœud.

Vous pouvez le faire avec une requête récursive:

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



0 commentaires

0
votes

Vous pouvez créer le chemin d'accès à chaque ligne, puis l'utiliser pour le tri. La construction utilise un CTE récursif:

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;

Ici est un violon db .


0 commentaires

0
votes

Pas besoin de récursion, utilisez simplement un tri intelligent!

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 commentaires

1
votes

Une autre option consiste à utiliser le type de données hierarcyid

Exemple

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

Retours

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


0 commentaires