2017-01-27 4 views
2

Ich habe Tabelle wie ein Baum wie hier;SQL Server Daten aus hierarchischer Tabelle mit Eltern und Kindern

Id ParentId Name 
-- -------- --- 
    1 NULL  A 
    2 1   B 
    3 2   F 
    4 3   C 
    5 3   D 
    6 1   E 
    7 2   G 
    8 NULL  M 
    9 8   N 
    10 8  O 
    11 10  P 


    1-A 
    2-B 
     3-F 
     4-C 
     5-D 
     7-G 
    6-E 
    8-M 
    9-N 
    10-O 
     11-P 

Ich habe dies bisher versucht;

WITH  Relation (Id, ParentId, Name, [level], [orderSequence]) 
AS  (SELECT r.Id, 
       r.ParentId, 
       r.Name, 
       0, 
       CAST (r.Id AS VARCHAR (2500)) 
      FROM Report AS r 
      WHERE r.Id = @rid 
      UNION ALL 
      SELECT p.Id, 
       p.ParentId, 
       p.Name, 
       rl.[level] + 1, 
       CAST (rl.orderSequence + '_' + CAST (p.Id AS VARCHAR) AS VARCHAR (2500)) 
      FROM Report AS p INNER JOIN Relation AS rl ON p.ParentId = rl.Id) 


SELECT rl.* 
FROM relation AS rl 

Aber es gibt nur childs zurück. Wie kann ich Knoten alle Eltern mit allen Kindern erhalten Sample-Ausgabe, die ich für Knoten Id = 3-F erhalten möchte;

Id ParentId Name 
-- -------- --- 
1 NULL  A 
2 1   B 
3 2   F 
4 3   C 
5 3   D 


1-A 
    2-B 
    3-F 
     4-C 
     5-D 
+0

Ich glaube, Sie zur Vereinigung zwei rekursiven CTEs haben werden - eine für das Erhalten der Nachkommen der Baumknoten und der zweite für die Vorgänger. –

Antwort

2

Sie brauchen nur zwei rekursiven CTEs, eine für die Eltern und eine für die Kinder:

declare @t table(Id int,ParentId int,Name nvarchar(1)); 
insert into @t values (1,NULL,'A'),(2,1,'B'),(3,2,'F'),(4,3,'C'),(5,3,'D'),(6 ,1,'E'),(7 ,2,'G'),(8 ,NULL,'M'),(9,8,'N'),(10,8,'O'),(11,10,'P'); 

declare @Id int = 3; 

with Parents as 
(
    select Id 
      ,ParentId 
      ,Name 
    from @t 
    where Id = @Id 

    union all 

    select t.Id 
      ,t.ParentId 
      ,t.Name 
    from @t t 
     inner join Parents p 
      on t.Id = p.ParentId 
),Children as 
(
    select Id 
      ,ParentId 
      ,Name 
    from @t 
    where Id = @Id 

    union all 

    select t.Id 
      ,t.ParentId 
      ,t.Name 
    from @t t 
     inner join Children c 
      on t.ParentId = c.Id 
) 
select * 
from Parents 

union all 

select * 
from Children 
where Id <> @Id 
order by Id; 

Ausgang:

+----+----------+------+ 
| Id | ParentId | Name | 
+----+----------+------+ 
| 1 | NULL  | A | 
| 2 | 1  | B | 
| 3 | 2  | F | 
| 4 | 3  | C | 
| 5 | 3  | D | 
+----+----------+------+ 
+0

Danke für diese sichere und richtige Antwort! + 1 –

3
Declare @Tags table (id int,ParentId int,Name varchar(50)) 
Insert into @Tags values 
(1, NULL  ,'A') 
,(2, 1   ,'B') 
,(3, 2   ,'F') 
,(4, 3   ,'C') 
,(5, 3   ,'D') 
,(6, 1   ,'E') 
,(7, 2   ,'G') 
,(8, NULL  ,'M') 
,(9, 8   ,'N') 
,(10, 8  ,'O') 
,(11, 10  ,'P') 

Declare @Top int   = null  --<< Sets top of Hier Try 3 
Declare @Fetch int   = null  --<< Null for Entier Hier 
Declare @Nest varchar(25) = '|-----' --<< Optional: Added for readability 

;with cteP as (
     Select Seq = cast(1000+Row_Number() over (Order by Name) as varchar(500)) 
      ,ID 
      ,ParentId 
      ,Lvl=1 
      ,Name 
     From @Tags 
     Where IsNull(@Top,-1) = case when @Top is null then isnull(ParentId ,-1) else ID end 
     Union All 
     Select Seq = cast(concat(p.Seq,'.',1000+Row_Number() over (Order by r.Name)) as varchar(500)) 
      ,r.ID 
      ,r.ParentId 
      ,p.Lvl+1 
      ,r.Name 
     From @Tags r 
     Join cteP p on r.ParentId = p.ID) 
    ,cteR1 as (Select *,R1=Row_Number() over (Order By Seq) From cteP) 
    ,cteR2 as (Select A.ID,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.ID) 
    ,cteHB as (
       Select A.R1 
         ,B.R2 
         ,A.ID 
         ,A.ParentId 
         ,A.Lvl 
         ,Name = Replicate(@Nest,A.Lvl-1) + concat(A.ID,'-',A.Name) 
       From cteR1 A 
       Join cteR2 B on A.ID=B.ID 
       ) 
Select Distinct A.* 
From cteHB A 
Join cteHB B on B.ID = IsNull(@Fetch,A.ID) and (@Fetch is not null and A.R1 between B.R1 and B.R2 or B.R1 between A.R1 and A.R2) 
Order By A.R1 

Returns

enter image description here

Zusätzliche Optionen:

Wenn @Fetch = NULL Stellen Sie die gesamte Hierarchie erhalten

enter image description here

+0

Danke für die tolle Antwort! –

+0

Mit [diesem Web-Tool - Sinnvolle Lösungen] (https://senseful.github.io/web-tools/text-table/)) können Sie aus dem Ergebnisraster kopieren und in ihre Eingabe einfügen und auf create table klicken, um zu erhalten eine Code-freundliche Version der Tabelle anstelle von Bildern. – SqlZim

+0

@SqlZim Nein, ich bevorzuge Bilder. Es ist eine bessere Sicht –

Verwandte Themen