2015-08-05 5 views
10

Angenommen ich diese Tabelle haben: (c ein Kind von Eltern ist p)Sortierte Hierarchiezeilen im SQL Server anzeigen?

c p 
------ 
40 0 
2 3 
2 40 
3 1 
7 2 
1 0 

Wo (0 bedeutet root) - Ich möchte die Reihenfolge wählen, wie angezeigt werden:

c b 
------ 
1 0 
3 1 
2 3 
40 0 
2 40 
7 2 

Das ist denn wir haben 2 Wurzeln (1,40) und 1 < 40.

So beginnen wir bei 1 und dann darunter anzeigen - alles ist es Nachkommen.

Dann kommen wir zu 40. gleiche Logik wieder.

enter image description here

Frage:

Wie kann ich es tun? + Suche nach Hierarchieebene *

Ich habe gelang es rekursiv angezeigt werden (nicht sicher, ob es allerdings hilft) *

WITH cte(c, p) AS (
    SELECT 40, 0 UNION ALL 
    SELECT 2,3 UNION ALL 
    SELECT 2,40 UNION ALL 
    SELECT 3,1 UNION ALL 
    SELECT 7,2 UNION ALL 
    SELECT 1,0 
    ) , cte2 AS(
     SELECT c, 
       p, 
       PLevel = 1 
     FROM cte 
     WHERE p = 0 
     UNION ALL 
     SELECT cte.c, 
       cte.p, 
       PLevel = cte2.PLevel + 1 
     FROM cte 
       INNER JOIN cte2 
        ON cte2.c = cte.p 
    ) 

SELECT * 
FROM cte2 

Full SQL fiddle

Antwort

8

Sie haben es fast geschafft. Fügen Sie einfach eine rank hinzu, um jede Gruppe zu identifizieren und sortieren Sie die Daten danach.

Auch, da Sie mit komplexeren Hierarchie arbeiten müssen wir den Wert [level] ändern. In ist jetzt keine Zahl, lege den vollständigen Pfad des aktuellen Elements zu seinem Elternelement. Wobei \ Eltern bedeutet. Zum Beispiel kann die folgende Zeichenfolge:

\ 1 \ 5 \ 4 \ 1

stellt die Hierarchie unter:

1 
    --> 5 
     --> 4 
      --> 1 

ich die Idee von hierarchyid Typ erhalten. Vielleicht möchten Sie darüber nachdenken, Hierarchien zu speichern, da es praktische Funktionen zum Arbeiten mit solchen Strukturen bietet.


Hier ist voll Beispiel mit den neuen Daten zu arbeiten:

DECLARE @DataSource TABLE 
(
    [c] TINYINT 
    ,[p] TINYINT 
); 

INSERT INTO @DataSource ([c], [p]) 
VALUES (1,0) 
     ,(3, 1) 
     ,(2, 3) 
     ,(5,1) 
     ,(7, 2) 
     ,(40, 0) 
     ,(2, 40); 

WITH DataSource ([c], [p], [level], [rank])AS 
(
    SELECT [c] 
      ,[p] 
      ,CAST('/' AS VARCHAR(24)) 
      ,ROW_NUMBER() OVER (ORDER BY [c] ASC) 
    FROM @DataSource 
    WHERE [p] = 0 
    UNION ALL 
    SELECT DS.[c] 
      ,DS.[p] 
      ,CAST(DS1.[level] + CAST(DS.[c] AS VARCHAR(3)) + '/' AS VARCHAR(24)) 
      ,DS1.[rank] 
    FROM @DataSource DS 
    INNER JOIN DataSource DS1 
     ON DS1.[c] = DS.[p] 
) 
SELECT [c] 
     ,[p] 
FROM DataSource 
ORDER BY [Rank] 
     ,CAST([level] AS hierarchyid); 

enter image description here

Wieder, achten Sie auf den Knoten (7,2), die in den beiden Gruppen (auch in Ihrem Beispiel) beteiligt . Ich denke, das ist nur ein Beispieldaten und Sie haben eine Möglichkeit zu definieren, wo der Knoten enthalten sein sollte.

Verwandte Themen