Slect ricorsiva

lunedì 09 dicembre 2013 - 10.11
Tag Elenco Tags  SQL Server 2008 R2

paolagumi Profilo | Junior Member

Buongiorno,
in sql server 2008 ho un db fatto così:
id, username, idResponsabile.
è l'elenco dei dipendenti di un'azienda, ognuno ha un id e uno username e il proprio responsabile, gerarchicamente fino al direttore dove l'idresponsabile è NULL.
Devo ottenere un elenco di tutti i subordinati di un dirigente, che sotto ha poniamo tre livelli,
esempio:
direttore generale= Disney
dirigente: Topolino, che ha come subordinato Pluto
dirigente: Pippo che è da solo
dirigente: Zio Paperone, ha come subordinati: Paperino, che a sua volta sotto ha Qui-Quo-Qua,
Nonna Papera che a sua volta sotto ha Ciccio.
Se seleziono digirente Zio Paperone come username,
vorrei ottenere come risultato questo elenco:
Paperino
Qui
Quo
Qua
Nonnma Papera
Ciccio.
L'ordine non ha importanza.
Ora faccio così:

declare @IdPrincipale as int

set @IdPrincipale = (select Id from Utenti where UserName = 'Zio Paperone')

select Id, UserName, IdResponsabile from Utenti where IdResponsabile = @IdPrincipale

così ottengo questa lista:
Paperino
Nonna Papera

come faccio ad estrarre i loro subordinati? ho provato ad impostare while con exists varie...ma non ottengo nulla,
perchè non so come si fa.
qualcuno mi può aiutare?
grazie
Paola

renarig Profilo | Expert

Vuole essere solo uno spunto di riflessione assolutamente non risolutivo
Proviamo a stilizzare i nomi

NomeTabella = Tabe
- Id = IdPP ( Il tuo @IdPrincipale ) ( che assumiamo uguale a 3 )
- username = UsNo
- idResponsabile = IdRe


per arrivare solo al 3° livello è relativamente semplice
ma se vuoi andare oltre la difficolta aumenta in modo esponenziale
( mi sa che è meglio fare dall'inizio un ciclo )
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

alx_81 Profilo | Guru

Ciao a tutti,
che ne dite di una CTE ricorsiva? Osservate il seguente esempio:

use tempdb; GO CREATE TABLE #Gerarchia ( id int NOT NULL PRIMARY KEY CLUSTERED , username varchar(30) NOT NULL , idResponsabile int NULL ); INSERT INTO #Gerarchia (id, username, idResponsabile) VALUES (1, 'Disney', NULL) , (2, 'Topolino', 1) , (3, 'Pippo', 1) , (4, 'Zio Paperone', 1) , (5, 'Paperino', 4) , (6, 'Qui', 5) , (7, 'Quo', 5) , (8, 'Qua', 5) , (9, 'Nonna Papera', 5) , (10, 'Ciccio', 9); SELECT id , username , idResponsabile FROM #Gerarchia; /* id username idResponsabile ----------- ------------------------------ -------------- 1 Disney NULL 2 Topolino 1 3 Pippo 1 4 Zio Paperone 1 5 Paperino 4 6 Qui 5 7 Quo 5 8 Qua 5 9 Nonna Papera 5 10 Ciccio 9 */ DECLARE @id int = 4; -- ZIO PAPERINO -- Creazione della CTE Ricorsiva WITH CTEGerarchia (idResponsabile, idImpiegato, UserName, Livello) AS ( -- Testata (per far partire la ricorsione) SELECT G.idResponsabile , G.id , G.username , Livello = 0 FROM #Gerarchia G WHERE G.idResponsabile = @id UNION ALL -- Membro ricorsivo SELECT G.idResponsabile , G.id , G.username , Livello + 1 FROM #Gerarchia G JOIN CTEGerarchia C ON G.idResponsabile = C.idImpiegato ) -- Lettura SELECT '| ' + CAST(REPLICATE('---', Livello) AS varchar(30)) + ' | ' + UserName FROM CTEGerarchia C; /* ----------------------------------------------------------------- | | Paperino | --- | Qui | --- | Quo | --- | Qua | --- | Nonna Papera | ------ | Ciccio */ -- cleanup DROP TABLE #Gerarchia;
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://blogs.dotnethell.it/suxstellino
http://suxstellino.wordpress.com
http://mvp.microsoft.com/profiles/Alessandro.Alpi

renarig Profilo | Expert

>che ne dite di una CTE ricorsiva? Osservate il seguente esempio:

secondo me è ottima

.

paolagumi Profilo | Junior Member

grazie, ottimo!
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5