|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
[access]Problema query con 'NOT LIKE'
Salve, sto lavorando ad un db di ricette con access e vorrei creare una query di ricerca delle ricette che NON contengano un determinato ingrediente ma che facciano parte di una certa categoria (es. tutte le ricette del tipo Biscotti che non contengono ricotta).
Le tabelle sono così strutturate: - ricetta (id, id_tipo (FK)) - ingredienti (id) - ingredientiRicetta (ID,id_ricetta (FK),id_ingredienti (FK)) - tipo (id) ho creato una query con il not like ma non funziona perché mi esclude l’ingrediente (selezionato come parametro esterno) ma non la ricetta che lo contiene. Come potrei risolvere questo problema? Grazie in anticipo Ciao Silvia |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quale query hai scritto?
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#3 |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
la query è questa, ma considera che ci sono anche altre tabelle coinvolte:
SELECT DISTINCTROW [Indice ricette].id, [Indice ricette].titolo, [Indice ricette].pagina, dox.descrizione, tipologia.tipologia, [Indice ricette].foto, [Indice ricette].istruzioni FROM Ingredienti INNER JOIN ((dox INNER JOIN (tipologia INNER JOIN [Indice ricette] ON tipologia.id_tipo = [Indice ricette].tipologia) ON dox.id_dox = [Indice ricette].dox) INNER JOIN IngredientiRicetta ON [Indice ricette].id = IngredientiRicetta.IDRicetta) ON Ingredienti.IDIngrediente = IngredientiRicetta.IDIngrediente WHERE (((Ingredienti.Ingrediente) Not Like ("*" & [param] & "*")) AND (([Indice ricette].tipologia)=[param2])) OR ((([Indice ricette].tipologia1)=[param2])) OR ((([Indice ricette].tipologia2)=[param2])); |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Devi scrivere una query a mano, non con il compositore di Access.
Dovrai scrivere una query che in Italiano suona come: Selezionare tutte le ricette che facciano parte di una categoria X data, ma che non contengano neppure una volta l'ingrediente Y. Dove quel "neppure una volta" si traduce con la clausola NOT EXISTS Qualcosa come Codice:
SELECT * FROM RICETTE WHERE categoria = 'X' AND NOT EXISTS ( SELECT 1 FROM Ingredienti WHERE Ricette.IDRicetta=Ingredienti.IDRicetta AND Ingredienti.Nome LIKE 'asdf%' )
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#5 |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
ci avevo provato senza il compositore, usando una select dentro una select. non conoscevo però il costrutto 'not exists'..
ci provo subito... in ogni caso grazie!!!! |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Dal momento che hai giustamente definito una tabella di raccordo IngredientiRicetta, per tagliare la relazione Molti-Molti tra Ricetta e Ingredienti, usiamo quella. Inoltre noto che in pratica i tuoi vari id sono chiavi e al tempo stesso descrizione dell'entità che rappresentano ( in pratica non fai un id numerico + descrizione-testo ), perciò la risolverei così : Codice:
SELECT DISTINCT Ricetta.id, Ricetta.id_tipo FROM Ricetta, IngredientiRicetta WHERE Ricetta.id = IngredientiRicetta.id_ricetta AND Ricetta.id_tipo = 'Biscotti' AND NOT EXISTS ( SELECT 1 FROM IngredientiRicetta WHERE Ricetta.id = IngredientiRicetta.id_ricetta AND IngredientiRicetta.id_ingredienti = 'ricotta' ) ![]() |
|
![]() |
![]() |
![]() |
#7 |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
Siete fantastici!!!!!! Grazie!!!!!
Non conoscevo la clausola EXISTS che invece mi ha risolto tutto! P.S. Per Marco: la clausola like la devo lasciare perchè la ricerca tra gli ingredienti è la più varia (es. esiste farina ma anche farina tipo 00) Ecco la query finalmente funzionante... SELECT [Indice ricette].id, [Indice ricette].titolo FROM [Indice ricette] WHERE [Indice ricette].tipologia=[param2] or ([Indice ricette].tipologia1=[param2] or [Indice ricette].tipologia2=[param2]) and not exists (select 1 from ingredienti, ingredientiricetta where ingredienti.idingrediente=ingredientiricetta.idingrediente and ingredienti.ingrediente like '*' & [param] & '*'); |
![]() |
![]() |
![]() |
#8 | |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
Quote:
...come non detto... non funziona bene perchè la descrizione dell'ingrediente sta nella tabella ingrediente... mi dà molti più record di quanti me ne aspetti.... ![]() |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Ma di cosa hai bisogno, di un elenco di ricette o di un elenco di ingredienti?
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#10 |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
![]() Se vuoi posto un DB Access di prova che lo dimostra. Bisogna solo intendersi sullo schema del DB. Tu hai postato questo schema : - ricetta (id, id_tipo (FK)) - ingredienti (id) - ingredientiRicetta (ID,id_ricetta (FK),id_ingredienti (FK)) - tipo (id) Se in Ingredienti c'è un solo campo "id", mi sembra chiaro che non può essere un id numerico, sennò gli ingredienti sarebbero numeri puri, perciò ho ipotizzato che le tue chiavi primarie ( e relative FK ) fossero di tipo testo e contenessero il nome stesso ( che deve essere univoco ) dell'ingrediente, o della ricetta, e così via... Come già scritto, ho postato quella query attenendomi fedelmente a quello schema del DB, se ora lo schema del DB è cambiato dovrai adattare la query di conseguenza... In ogni caso è sempre difficile suggerire query di qualsiasi genere, finchè non è chiaro e definito una volta per tutte lo schema. ![]() |
|
![]() |
![]() |
![]() |
#12 | |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
Quote:
![]() la tabella ingredienti (id, descrizione) es, id=1 desc=farina tipo 0 id=2 desc=farina tipo 00 ecc, ecc ed ecco perchè ho necessità di usare il like... |
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Codice:
SELECT DISTINCT Ricetta.id, Ricetta.id_tipo FROM Ricetta, IngredientiRicetta, Ingredienti WHERE Ricetta.id = IngredientiRicetta.id_ricetta AND IngredientiRicetta.id_ingredienti = Ingredienti.id AND Ricetta.id_tipo = 'Biscotti' AND NOT EXISTS ( SELECT 1 FROM IngredientiRicetta, Ingredienti WHERE Ricetta.id = IngredientiRicetta.id_ricetta AND IngredientiRicetta.id_ingredienti = Ingredienti.id AND Ingredienti.descrizione LIKE 'ricotta' ); ![]() |
|
![]() |
![]() |
![]() |
#14 |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
non risponde... rimane in esecuzione e basta...
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Da me funziona, ma evidentemente ci sono ancora differenze di schema che non hai chiarito ( giudicando dalla query al tuo post #3... ).
Quando si fanno domande come la tua deve essere CHIARO lo schema, sennò è tutto inutile. Altro consiglio : evita gli spazi nelle definizioni a livello del DB : [Indice ricette] >> IndiceRicette, o Indice_ricette. |
![]() |
![]() |
![]() |
#16 |
Junior Member
Iscritto dal: Jul 2008
Messaggi: 21
|
Funziona!
Ho solo dovuto togliere WHERE [Indice ricette].tipologia=[param2] or ([Indice ricette].tipologia1=[param2] or [Indice ricette].tipologia2=[param2]) la parte in rosso (sono campi che ho ereditato dalla vecchia versione di access che non aveva i campi multivalore). Funziona perfettamente cercando per tipo principale! GRAZIE!!!!! P.S. Per gli spazi nel nome tabella, non sai quanto li sto maledicendo..... ...peccato che per access non esista un bel refactor.... |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Per avere un elenco di ricette, non bisogna fare la JOIN con gli ingredienti.
Dovrebbe essere sufficiente la Codice:
SELECT * FROM Ricetta WHERE Ricetta.id_tipo = 'Biscotti' AND NOT EXISTS ( SELECT 1 FROM IngredientiRicetta WHERE Ricetta.id = IngredientiRicetta.id_ricetta AND IngredientiRicetta.id_ingredienti = 'ricotta' )
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Codice:
SELECT * FROM Ricetta WHERE Ricetta.id_tipo = 'Biscotti' AND NOT EXISTS ( SELECT 1 FROM IngredientiRicetta, Ingredienti WHERE Ricetta.id = IngredientiRicetta.id_ricetta AND IngredientiRicetta.id_ingredienti = Ingredienti.id AND Ingredienti.descrizione LIKE 'ricotta' );
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:17.