2013-05-20 9 views
5

Ho un auto correlati Tabella myTable come:SQL: come trovare le file foglia?

ID | RefID 
---------- 
1 | NULL 
2 | 1 
3 | 2 
4 | NULL 
5 | 2 
6 | 5 
7 | 5 
8 | NULL 
9 | 7 

ho bisogno di ottenere righe foglia su qualsiasi profondità

in base alla tabella di cui sopra, il risultato deve essere:

ID | RefID 
---------- 
3 | 2 
4 | NULL 
6 | 5 
8 | NULL 
9 | 7 

ringraziamento you

PS: la profondità può variare, qui è un esempio molto piccolo

Here is a visual demonstration of the sample data

+0

Vuoi dire "livello più basso solo di una gerarchia"? – gbn

+3

sì, l'inglese non è la mia lingua madre – armen

+1

Si prega di aggiornare i dati di esempio per mostrare i risultati quando 'la profondità può variare. Attualmente ci hai solo chiesto di risolvere il caso più semplice. Se vuoi risolvere anche il caso complesso, mostralo! –

risposta

7

Prova:

SELECT id, 
     refid 
FROM mytable t 
WHERE NOT EXISTS (SELECT 1 
        FROM mytable 
        WHERE refid = t.id) 
+1

Questo non si occuperà di una gerarchia profonda – gbn

+0

@gbn: cosa intendi? prestazione ? –

+0

no, se ci sono molti livelli. Funziona solo con dati di esempio – gbn

4
select ID, RefId 
from myTable t1 left join myTable t2 on t1.ID = t2.RefID 
where t2.RefID is null 
+0

Questo non affronterà una gerarchia profonda – gbn

+2

@gbn penso che lo farà. – paul

+2

Vedere i commenti sulle altre risposte: dipende da – gbn

7
DECLARE @t TABLE (id int NOT NULL, RefID int NULL); 

INSERT @t VALUES (1, NULL), (2, 1), (3, 2), (5, NULL), 
      (6, 5), (4, NULL), (7, 5), (8, NULL), (9, 8), (10, 7); 

WITH CTE AS 
(
    -- top level 
    SELECT id, RefID, id AS RootId, 0 AS CTELevel FROM @t WHERE REfID IS NULL 
    UNION ALL 
    SELECT T.id, T.RefID, RootId, CTELevel + 1 FROM @t T JOIN CTE ON T.RefID = CTE.id 
), Leafs AS 
(
    SELECT 
     id, RefID, DENSE_RANK() OVER (PARTITION BY CTE.RootId ORDER BY CTELevel DESC) AS Rn 
    FROM CTE 
) 
SELECT 
    id, RefID 
FROM 
    Leafs 
WHERE 
    rn = 1 
+4

La ricorsione non è necessaria per qualcosa di così semplice. Hai solo bisogno di controllare se ogni figlio di righe ha un figlio o no. Altre due risposte stanno funzionando bene, anche con i dati di esempio. Questo CTE manca tuttavia una fila 7,5? –

+0

@NenadZivkovic: hai ragione, è troppo complesso. Se la gerarchia si dirama, allora usi DENSE_RANK invece. Inoltre, è la foglia più bassa di ogni ramo da una radice, o solo la più bassa per ogni radice? – gbn

+0

@ypercube: puoi dire perché? –

Problemi correlati