Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

sql nadrzędne drzewo potomne z porządkiem sortowania

Rekurencyjne CTE ze specjalnym nadpisaniem sortowania. Zwróć uwagę na nadpisanie sortowania u dzieci 2 (nieznacznie zmodyfikowałem tabelę źródłową, aby przetestować tę umiejętność)

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);

Wynik:

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)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server, Jak ustawić automatyczny przyrost po utworzeniu tabeli bez utraty danych?

  2. Jak określić kolumnę, która ma być unikatowa w zakresie relacji w SQL Server 2008?

  3. Nie można połączyć się z localDB w VS2012 — wystąpił błąd związany z siecią lub specyficzny dla instancji podczas nawiązywania połączenia z SQL Server...

  4. Sformatuj numer telefonu w programie SQL Server (T-SQL)

  5. SQL Server 2005 Używanie DateAdd do dodawania dnia do daty