2015-08-05 13 views
10

considerando che io ho questa tabella: (c è un figlio di genitore p)Visualizzazione delle righe di gerarchia ordinate nel server SQL?

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

Dove (0 significa root) - Voglio che l'ordine di selezione per essere visualizzato come:

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

Ecco perché abbiamo 2 radici (1,40) e 1 < 40.

Quindi iniziamo da 1 e quindi visualizziamo sotto di esso - tutti i suoi discendenti.

Quindi arriviamo a 40. stessa logica ancora.

enter image description here

Domanda:

Come posso fare?

Sono riuscito a visualizzarlo in modo ricorsivo + trovando livello della gerarchia * (non so se è utile però) *

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

risposta

8

hai quasi fatto. Basta aggiungere uno rank per identificare ciascun gruppo e quindi ordinare i dati su di esso.

Inoltre, poiché si lavora con una gerarchia più complessa, è necessario modificare il valore [level]. In non è ora un numero, metti il ​​percorso completo dell'elemento corrente al suo genitore. Dove \ significa genitore. Ad esempio, la seguente stringa:

\ 1 \ 5 \ 4 \ 1

rappresenta la gerarchia di seguito:

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

ho reso l'idea da hierarchyid tipo. Si consiglia di considerare l'archiviazione delle gerarchie che lo utilizzano, poiché dispone di utili funzioni incorporate per l'utilizzo di tali strutture.


Qui è pieno esempio di lavoro con i nuovi dati:

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

Anche in questo caso, prestare attenzione al nodo (7,2) che partecipa nei due gruppi (anche nel tuo esempio) . Immagino che questo sia solo un campione di dati e che tu abbia un modo per definire dove deve essere incluso il nodo.

Problemi correlati