[QL Express] Problema con query...

giovedì 28 gennaio 2010 - 15.29

atsap Profilo | Newbie

Salve a tutti!
Ho questo problema, e non riesco a venirne a capo.

Assumiamo che io abbia un database così strutturato:
Tabella ricetta: idRicetta = 7 nomeRicetta = Lasagne idRicetta = 8 nomeRicetta = Brasato idRicetta = 9 nomeRicetta = Frittura

Diciamo che ho inserito i seguenti ingredienti:

Tabella ingredienti: idIngrediente = 1 nomeIngrediente = aglio idIngrediente = 2 nomeIngrediente = cipolla idIngrediente = 3 nomeIngrediente = pepe idIngrediente = 4 nomeIngrediente = olio

Assumiamo, per semplicità, queste associazioni:

Tabella ing_ricette: idRicetta = 7 idIngrediente = 1 idRicetta = 7 idIngrediente = 2 idRicetta = 8 idIngrediente = 1 idRicetta = 8 idIngrediente = 3 idRicetta = 9 idIngrediente = 4 idRicetta = 9 idIngrediente = 1 idRicetta = 9 idIngrediente = 3

per cui, avremo che le Lasagne avranno come ingrediente aglio + cipolla, il brasato avrà aglio e pepe e infine la frittura avrà olio, aglio e pepe. Dunque, tutte le ricette hanno l'aglio.
Se io strutturassi la query in questo modo "SELECT ...... WHERE .... idIngrediente = 1 AND idIngrediente = 3" non otterrei nessun risultato (penso!) perché l'idIngrediente non può assumere due valori nello stesso momento (o è 1 oppure è 3). Per cui, non otterei, come invece mi aspetto, il brasato e la frittura.
Se invece strutturassi la query così: "SELECT ....... WHERE .... idIngrediente = 1 OR idIngrediente = 3" otterrei tutti i risultati, perché, sebbene l'ingrediente 3 (il pepe) non sia presente in tutte le ricette, l'ingrediente 1 (l'aglio!) è invece abbinato a tutte.
Come posso fare per ottenere tutte le ricette che contengono SOLO gli ingredienti 1 e 3?

Grazie a tutti!

lbenaglia Profilo | Guru

>Come posso fare per ottenere tutte le ricette che contengono
>SOLO gli ingredienti 1 e 3?

Ciao Dino,

La soluzione consiste nel restituire le righe che soddisfano entrambi gli ingredienti considerando però solo quelle che li contengono entrambi (che è più o meno quello che hai scritto tu )
Ma come si fa?
Basta raggruppare le righe per ricetta determinandone il numero, restituendo quelle il cui conteggio è pari a 2 (dato che gli ingredienti specificati nel filtro sono 2).

USE tempdb; CREATE TABLE dbo.Ricetta( RicettaID int NOT NULL, Nome varchar(10) NOT NULL, CONSTRAINT PK_Ricetta PRIMARY KEY(RicettaID) ); CREATE TABLE dbo.Ingredienti( IngredienteID int NOT NULL, Nome varchar(10) NOT NULL, CONSTRAINT PK_Ingredienti PRIMARY KEY(IngredienteID) ); CREATE TABLE dbo.RicetteIngredienti( RicettaID int NOT NULL, IngredienteID int NOT NULL, CONSTRAINT PK_RicetteIngredienti PRIMARY KEY(RicettaID, IngredienteID), CONSTRAINT FK_RicetteIngredienti_Ricetta FOREIGN KEY(RicettaID) REFERENCES dbo.Ricetta(RicettaID), CONSTRAINT FK_RicetteIngredienti_Ingredienti FOREIGN KEY(IngredienteID) REFERENCES dbo.Ingredienti(IngredienteID) ); INSERT dbo.Ricetta VALUES (7, 'Lasagne') , (8, 'Brasato') , (9, 'Frittura'); INSERT dbo.Ingredienti VALUES (1, 'Aglio') , (2, 'Cipolla') , (3, 'Pepe') , (4, 'Olio'); INSERT dbo.RicetteIngredienti VALUES (7, 1) , (7, 2) , (8, 1) , (8, 3) , (9, 4) , (9, 1) , (9, 3); SELECT R.RicettaID, R.Nome FROM dbo.Ricetta AS R JOIN dbo.RicetteIngredienti AS RI ON R.RicettaID = RI.RicettaID WHERE RI.IngredienteID IN(1, 3) GROUP BY R.RicettaID, R.Nome HAVING COUNT(*) = 2; /* Output: RicettaID Nome ----------- ---------- 8 Brasato 9 Frittura (2 row(s) affected) */ DROP TABLE dbo.RicetteIngredienti, dbo.Ingredienti, dbo.Ricetta;

>Grazie a tutti!
Prego.

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

atsap Profilo | Newbie

Che dire... non ci avrei mai pensato. Brillante e funzionale soluzione!
Accetto la risposta e ti ringrazio tanto :-)
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-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5