QUERY FORSE IMPOSSIBILE?

martedì 26 febbraio 2008 - 16.58

mircoso Profilo | Newbie

Ciao a Tutti, ho un problema a fare una query che vi vado a illustrare

TBL_CATEGORIA

ID --------- CATEGORIA --------- ID_CAT_PADRE
1 FERRAMENTA 0
2 VITI 1
3 VARIE 0
4 BULLONI 1
5 VITI A CROCE 2


- FERRAMENTA
|- VITI
|- - VITI A CROCE
|- BULLONI
- VARIE


Quando scelgo ferramenta devo vadere anche il record VITI e VITI A CROCE.

Come posso fare? qualche idea?

Grazie 1000 a tutti per l'aiuto che mi darete


Wamba Profilo | Expert

Ciao, con una query forse si, ma in una stored è fattibile.
-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
blogs.ugidotnet.org/WamBlog/
www.intellimaker.com

alx_81 Profilo | Guru

>Ciao a Tutti,
Cia e benvenuto su DotNetHell!

>Come posso fare? qualche idea?
Che DBMS utilizzi?
>
>Grazie 1000 a tutti per l'aiuto che mi darete
di nulla!
Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

lbenaglia Profilo | Guru

>TBL_CATEGORIA
>
>ID --------- CATEGORIA --------- ID_CAT_PADRE
>1 FERRAMENTA 0
>2 VITI 1
>3 VARIE 0
>4 BULLONI 1
>5 VITI A CROCE 2
>
>
>- FERRAMENTA
>|- VITI
>|- - VITI A CROCE
>|- BULLONI
>- VARIE
>
>
>Quando scelgo ferramenta devo vadere anche il record VITI e VITI
>A CROCE.
>
>Come posso fare? qualche idea?

Ciao Mirco,

La soluzione dipende dal DBMS che stai utilizzando.
Ad ogni modo mi permetto di farti 2 osservazioni:

1) In base ai dati che hai postato deduco che la struttura della tabella è sbagliata, dato che non può esistere una foreign key tra ID_CAT_PADRE e ID, visto che non esiste alcuna riga con ID = 0;

2) Se vuoi visualizzare sia FERRAMENTA che VARIE occorre un padre comune (nel mio esempio lo chiamerò CATEGORIE).

Ti allego una soluzione per SQL Server, basata su una Multistatement Table-valued Function:

USE tempdb; CREATE TABLE dbo.TBL_CATEGORIA( ID int NOT NULL, CATEGORIA varchar(20) NOT NULL, ID_CAT_PADRE int NULL, CONSTRAINT PK_CATEGORIA PRIMARY KEY(ID), CONSTRAINT FK_CATEGORIA_ID_CAT_PADRE_ID FOREIGN KEY(ID_CAT_PADRE) REFERENCES dbo.TBL_CATEGORIA(ID) ); INSERT dbo.TBL_CATEGORIA VALUES(0, 'CATEGORIE', NULL); INSERT dbo.TBL_CATEGORIA VALUES(1, 'FERRAMENTA', 0); INSERT dbo.TBL_CATEGORIA VALUES(2, 'VITI', 1); INSERT dbo.TBL_CATEGORIA VALUES(3, 'VARIE', 0); INSERT dbo.TBL_CATEGORIA VALUES(4, 'BULLONI', 1); INSERT dbo.TBL_CATEGORIA VALUES(5, 'VITI A CROCE', 2); GO CREATE FUNCTION dbo.ufn_GetSubtree( @ID_CAT_PADRE AS int ) RETURNS @tree table( ID int NOT NULL, ID_CAT_PADRE int NULL, CATEGORIA varchar(20) NOT NULL, lvl int NOT NULL, path varchar(900) NOT NULL ) AS BEGIN DECLARE @lvl AS int SELECT @lvl = 0 INSERT INTO @tree SELECT ID, ID_CAT_PADRE, CATEGORIA, @lvl, '.' + CAST(ID AS varchar(10)) + '.' FROM dbo.TBL_CATEGORIA WHERE ID = @ID_CAT_PADRE WHILE @@ROWCOUNT > 0 BEGIN SET @lvl = @lvl + 1 INSERT INTO @tree SELECT C.ID, C.ID_CAT_PADRE, C.CATEGORIA, @lvl, T.path + CAST(C.ID AS varchar(10)) + '.' FROM dbo.TBL_CATEGORIA AS C JOIN @tree AS T ON C.ID_CAT_PADRE = T.ID AND T.lvl = @lvl - 1 END RETURN END GO SELECT REPLICATE ('|-', lvl) + CATEGORIA AS CATEGORIA FROM ufn_GetSubtree(0) ORDER BY path; /* Output: CATEGORIA ------------------- CATEGORIE |-FERRAMENTA |-|-VITI |-|-|-VITI A CROCE |-|-BULLONI |-VARIE (6 row(s) affected) */ DROP FUNCTION dbo.ufn_GetSubtree; DROP TABLE dbo.TBL_CATEGORIA;

>Grazie 1000 a tutti per l'aiuto che mi darete
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

mircoso Profilo | Newbie

Ciao Wamba, Alx81 e lbenaglia

spero di essere esauriente nella risposta, uso SQL EXPRESS 2005.
Purtroppo come si è capito in fase di progettazione probabilmente si è fatto un errore strutturale dove abbiamo racchiuso le vaire "CATTEGORIE" e "SOTTO CATTEGORIE" in un'unica tabella dove racchiudevano sia i padri che i relativi figli.

Collegate a queste cattegorie ho dei record (Oggetti) che vengono ragruppati e quando mi selezionano un padre devo riuscire a tirare fuori tutte le sotto cattegorie figle e i relativi oggetti e in un unica query per poterla elaborare poi con il mio programma in vb net


Domani mattina appena sarò in uficio proverò ad applicare la solizione data da lbenaglia.

Nel frattempo GRAZIE 1000 per l'aiuto

Mirco

ps. se vi venisse in mente altro per aiutarmi ben venga....

lbenaglia Profilo | Guru

>spero di essere esauriente nella risposta, uso SQL EXPRESS 2005.
>Purtroppo come si è capito in fase di progettazione probabilmente
>si è fatto un errore strutturale dove abbiamo racchiuso le vaire
>"CATTEGORIE" e "SOTTO CATTEGORIE" in un'unica tabella dove racchiudevano
>sia i padri che i relativi figli.
Non vedo alcun errore nel definire una tabella gerarchica, occhio solo a definirla nel modo corretto

>Collegate a queste cattegorie ho dei record (Oggetti) che vengono
>ragruppati e quando mi selezionano un padre devo riuscire a tirare
>fuori tutte le sotto cattegorie figle e i relativi oggetti e
>in un unica query per poterla elaborare poi con il mio programma
>in vb net
Qua si capisce poco.
Devi postare un esempio completo con la struttura delle tabelle (CREATE TABLE), alcune righe di prova (INSERT INTO) ed il result set finale che vorresti ottenere, esattamente come ho fatto io nel mio esempio.

>Nel frattempo GRAZIE 1000 per l'aiuto
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

mircoso Profilo | Newbie

Hai ragione scusa!!!

mi ci vuole un pò a preparare il tutt anche perchè ora non sono in uff... comunque lo preparo e lo mando...

Grazie

alx_81 Profilo | Guru

Visto che utilizzi SQL Server 2005, ti propongo la soluzione con le CTE utilizzate ricorsivamente:

USE tempdb; GO CREATE TABLE dbo.TBL_CATEGORIA ( ID int NOT NULL , Categoria varchar(30) NOT NULL , IDPadre int NULL , CONSTRAINT PK_TBL_CATEGORIA PRIMARY KEY CLUSTERED ( ID ) ) GO INSERT INTO dbo.TBL_CATEGORIA (ID, Categoria, IDPadre) VALUES (1, 'TUTTE', NULL) INSERT INTO dbo.TBL_CATEGORIA (ID, Categoria, IDPadre) VALUES (2, 'FERRAMENTA', 1) INSERT INTO dbo.TBL_CATEGORIA (ID, Categoria, IDPadre) VALUES (3, 'VITI', 2) INSERT INTO dbo.TBL_CATEGORIA (ID, Categoria, IDPadre) VALUES (4, 'VARIE', 1) INSERT INTO dbo.TBL_CATEGORIA (ID, Categoria, IDPadre) VALUES (5, 'BULLONI', 2) INSERT INTO dbo.TBL_CATEGORIA (ID, Categoria, IDPadre) VALUES (6, 'VITI A CROCE', 3) GO ALTER TABLE dbo.TBL_CATEGORIA ADD CONSTRAINT FK_TBL_CATEGORIA_TBL_CATEGORIA FOREIGN KEY (IDPadre) REFERENCES dbo.TBL_CATEGORIA (ID) GO ;WITH Categorie (ID, Categoria, IDPadre, Livello, Ordine) AS ( SELECT ID , Categoria , IDPadre , Livello = 0 , Ordine = CAST(ID AS varchar(10)) FROM dbo.TBL_CATEGORIA WHERE IDPadre IS NULL UNION ALL SELECT C.ID , C.Categoria , C.IDPadre , Livello = CT.Livello + 1 , Ordine = CAST(Ordine + CAST(C.ID AS varchar(10)) AS varchar(10)) FROM dbo.TBL_CATEGORIA AS C JOIN Categorie AS CT ON C.IDPadre = CT.ID ) SELECT cast(REPLICATE('|- ', Livello) + Categoria AS varchar(50)) FROM Categorie ORDER BY Ordine /* -------------------------------------------------- TUTTE |- FERRAMENTA |- |- VITI |- |- |- VITI A CROCE |- |- BULLONI |- VARIE */

Come puoi notare la CTE (la with per intenderci) possiede una parte fissa, quella in cui ricavo il primo padre della gerarchia (che raggruppa tutti i record di livello inferiore), ed una ricorsiva, che è quella dopo la UNION ALL. Fai attenzione che, come diceva correttamente Lorenzo, devi avere un livello a monte (TUTTI) per visualizzare le tue FERRAMENTA e VARIE.
Dall'ultima select puoi andare in join sulle ulteriori tabelle che ti servono per ottenere tutti i dati che ti servono.
Ciao!
Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

mircoso Profilo | Newbie

MITICI!!!

Ho provato la soluzione di Alex e FUNZIONA!!! E' proprio ciò che cercavo!

Grazie 1000 di cuore...

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-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5