Aiuto per query con sql server 2005 express edition

giovedì 22 aprile 2010 - 01.49

zseven Profilo | Senior Member

Ciao a tutti,
avrei bisogno di un aiuto per una query che non riesco a risolvere.

Vi spiego la struttura.
Ho due tabelle:
tab_ricette
tab_ricette_strutture

Nella tabella tab_ricette_strutture ho un campo collegato all' id della ricetta e l'altro all'id della struttura, quindi così:
id_ricetta | id_struttura
dove vengono immagazzinate tutte le ricette associate ad una determinata struttura.

Adesso io vorrei mostrare tutte le ricette presenti nella tabella tab_ricette, senza quelle presenti nella tabella tab_ricette_strutture per una certa struttura.
Ho provato così,ipotizzando che la struttura abbia come id 27, ma non ottengo il risultato sperato:

SELECT tab_ricette.ID_ricette, tab_ricette.nome_ricetta, tab_ricette_strutture.id_ricetta, tab_ricette_strutture.id_struttura
FROM tab_ricette LEFT JOIN
tab_ricette_strutture ON tab_ricette.ID_ricette = tab_ricette_strutture.id_ricetta
AND tab_ricette_strutture.id_struttura <> 27

Mi vengono restituite sempre tutte le ricette.

Sapete darmi una mano?
Grazie mille

Klaus-zanini Profilo | Senior Member

Se non ho capito male tu hai una relazione 0 a molti giusto? Ossia una ricetta può avere da nessuna a molte strutture, dico bene?

Se è così con la tua query stai chiedendo di vedere tutte le ricette che non hanno un corrispondente id_struttura=27, quindi (per effetto della LEFT JOIN) ti mostra tutte le ricette, tutte le strutture di ogni ricetta ad eccezione di quella con id_struttura=27.

Ora il problema che vorrei capire è: tu vuoi trovare tutte le ricette che non hanno nemmeno un id_struttura? Se è così puoi fare:

SELECT tab_ricette.ID_ricette, tab_ricette.nome_ricetta, tab_ricette_strutture.id_ricetta, tab_ricette_strutture.id_struttura
FROM tab_ricette LEFT JOIN
tab_ricette_strutture ON tab_ricette.ID_ricette = tab_ricette_strutture.id_ricetta
WHERE tab_ricette_strutture.id_struttura IS NULL

zseven Profilo | Senior Member

Ciao,
scusa se rispondo solo adesso.
La query è perfetta così, grazie mille!!

zseven Profilo | Senior Member

Perdonami ho detto una stupidagine.

Lo risolve in un senso ma non in un altro.
Cerco di spiegarmi meglio.

Ho N strutture.
Ogni struttura può associare le ricette, io voglio fare in modo che vengano visualizzate tutte le ricette che QUELLA determinata struttura non ha ancora associato.
Il codice che mi hai dato va bene, ma se una seconda struttura ha già associato una ricetta, allora succede che la prima struttura non vede più quella ricetta, anche se in realtà la può associare.

So che è un pò complesso, ma spero di essermi spiegato meglio.

Grazie infinite

Klaus-zanini Profilo | Senior Member

Quindi, se non ho capito male potresti avere questi dati:
tab_ricette
ricetta 1
ricetta 2
ricetta 3

tab_ricette_strutture
struttura1 ricetta1
struttura1 ricetta2
struttura1 ricetta3
struttura2 ricetta1
struttura2 ricetta2
struttura3 ricetta2

il risultato della query che ti serve ti deve dare:
struttura2 ricetta3
struttura3 ricetta1
struttura3 ricetta3

In teoria a questo punto dovresti prima considerare tutti gli incroci (con un cross join) e poi mostrare quelli che non esistono ancora (magari con un NOT EXISTS). Guarda...non so se c'è qualcosa di più "pulito", ma io la farei così:

SELECT
T1.ID_ricette, T1.nome_ricetta,T2.id_struttura
FROM
tab_ricette T1
CROSS JOIN
(SELECT DISTINCT id_struttura FROM tab_ricette_strutture) T2
WHERE
NOT EXISTS(SELECT id_struttura,id_ricetta FROM tab_ricette_strutture
WHERE tab_ricette_strutture.Id_struttura = t2.id_struttura
AND tab_ricette_strutture.id_ricetta = t1.id_ricette)


zseven Profilo | Senior Member

Hai capito perfettamente il problema.
Adesso purtroppo non posso ancora provarlo, lo verificherò stasera e ti faccio sapere.

Grazie mille sempre per l'aiuto!

zseven Profilo | Senior Member

Ciao Klaus-zanini,
purtroppo c'è ancora qualcosa che non va.

In pratica se non esiste almeno una ricetta associata ad una struttura non viene visualizzata neanche una ricetta.

Purtroppo non riesco in nessuna maniera a risolvere questa query, è più complessa della mie conoscenze mi sa...
Riesci ad aiutarmi ancora una volta?

Grazie ancora.

Klaus-zanini Profilo | Senior Member

Ne sei sicuro? Io ho provato a creare le tabelle e ha fare dei test.
Ho inserito i record che avevo scritto nei primi post e ho aggiunto ora una id_struttura 4 con id_ricetta NULL e come risultato ho:

ID_Ricette nome_ricetta id_struttura
3 Rice3 2
1 Rice1 3
3 Rice3 3
1 Rice1 4
2 Rice2 4
3 Rice3 4


Non è che hai sbagliato qualcosa sulla query che ti ho mandato?
Altrimenti se puoi mettermi a disposizione una parte di dati potrei provare a simulare la tua realtà.

zseven Profilo | Senior Member

Ho appena riprovato con la query che mi hai scritto sul editor di sql server, e purtroppo il risultato è ancora quello.

Se esistono ricette ed esistono strutture, ma la tabella tab_ricette_strutture è vuota, non viene visualizzata nessuna ricetta.

Nel mio caso per esempio esistono 5 ricette nella tab_ricette, e 2 strutture nella tab_struttura.
LA tab_ricette_strutture è ancora vuota, perchè ancora nessuna struttura ha associato una ricetta.

Con questa situazione dall'esecuzione della query non mi viene restituito nessun risultato.

Hai qualche idea?
Grazie mille

Klaus-zanini Profilo | Senior Member

Ma tab_strutture da dove esce? Al primo post non avevi solo 2 tabelle (tab_ricette e tab_ricette_strutture)?
Magari ci sono dei valori di default su id_ricetta?

Puoi farmi avere un backup? Perché purtroppo diversamente non saprei che altri consigli darti...Io so simulato i tuoi casi in un database SQL e con la mia query funziona tutto...

zseven Profilo | Senior Member

Ciao, purtroppo il backup non riesco proprio a fartelo avere, cero di rispiegare meglio il tutto.

Le tabelle sono:
tab_ricette, tab_strutture, tab_ricette_strutture

la tabella tab_ricette_strutture ha due campi intesi come chiave secondaria:
id_ricetta | id_struttura

Adesso vale tutto il ragionamento fatto fin'ora, in pratica ogni struttura può associare
delle ricette, e questa associazione finisce nella tabella tab_ricette strutture.

Quindi quando io clicco per esempio nel pannello di controllo di una struttura che deve visualizzare
le ricette a disposizione, potrà vedere tutte le ricette tranne quelle che ha già associato.
Adesso con l'esempio che mi hai passato prima, se non esiste nessuna ricetta associata
da nessuna struttura non viene restituita nessuna ricetta dalla query.

Ti ringrazio infinitamente per l'aiuto, spero che questa spiegazione sia chiara e tu riesca ad aiutarmi.

Klaus-zanini Profilo | Senior Member

Forse allora si dovrebbe risolvere così cambiando nella T2 la tabella da tab_ricette_strutture a tab_strutture:

SELECT
T1.ID_ricette, T1.nome_ricetta,T2.id_struttura
FROM
tab_ricette T1
CROSS JOIN
(SELECT DISTINCT id_struttura FROM tab_strutture) T2
WHERE
NOT EXISTS(SELECT id_struttura,id_ricetta FROM tab_ricette_strutture
WHERE tab_ricette_strutture.Id_struttura = t2.id_struttura
AND tab_ricette_strutture.id_ricetta = t1.id_ricette)

zseven Profilo | Senior Member

Ciao,
ho provato il tuo codice, e se si risolve un problema, ce ne sta un altro che proprio non sono riuscito a risolvere in questi giorni.

Il problema è il seguente, cerco di spiegarti la situazione che viene a crearsi.

Immagina che ogni utente registrato può inserire una struttura, e ad ogni struttura associare le ricette.
Facciamo il caso concreto:
Esiste un UTENTE A ed un UTENTE B.
L'UTENTE A ha inserito una struttura (STRUTTURA 1), e due ricette (RICETTA 1 e RICETTA 2).
l'UTENTE B ha inserito una struttura (STRUTTURA 2), e 3 ricette (RICETTA 3, RICETTA 4, RICETTA 5)

Partendo dal caso che nessuno dei due utenti ha ancora associato ricette, allora il codice funziona correttamente, ed infatti se faccio il login come UTENTE A vedo correttamente divise le ricette che posso associare senza quelle che ho già associato.
Se l'UTENTE A associa una ricetta è tutto ok.

Ma se dopo faccio il login come UTENTE B, ecco che ho dei problemi, in quanto vedo le ricette raddoppiate.

Il codice che ho usato ha solo un'aggiunta dove verifico l'uguaglianza dell'utente che fa il login con la session, così da filtrare le ricette che ha inserito con quelle già inserite.
Non so se sono stato chiaro, so che è un pò difficile seguirmi.
Ti mostro il codice, spero riesca ad aiutarmi ancora.
Grazie mille

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Klaus-zanini Profilo | Senior Member

Ti aiuto ben volentieri!
Mi dovresti però specificare meglio la struttura delle tabelle ora che ci metti dentro anche l'utente...è solo un campo aggiuntivo su TAB_Strutture o si ripete anche nelle ricette e nella tabella di associazione?

zseven Profilo | Senior Member

Ciao Klaus,
id_utente si ripete sia nella tabella strutture che in quella delle ricette, ma non in quella dell'associazione... e mentre sto scrivendo mi sa che il problema è proprio quello.

in pratica al momento la situazione è la seguente:

TAB UTENTE ha come chiave primaria il campo ID_utenti
TAB RICETTE ha come chiave primaria ID_ricette e come chiave secondaria il campo id_utente che prende il valore di ID_utenti e mi dice quindi quale utente ha inserito questa ricetta
TAB STRUTTURE ha come chiave primaria ID_strutture e come chiave secondaria il campo id_utente che prende il valore ID_utenti e anche questo mi dice quale utente ha inserito questa struttura
TAB RICETTE STRUTTURE ha una chiave primaria ID_ricette_strutture e due chiavi secondarie che sono id_ricetta che prende il valore di ID_ricette e id_struttura che prende il valore di ID_strutture.

Forse non inserendo nella tabella di associazione anche la chiave secondaria id_utente non riesco ad ottenere il risultato sperato, giusto?

In pratica il ragionamento è il seguente:
Ogni utente ha la possibilità di inserire RICETTE e STRUTTURE.
Quando l'utente fa il login e quindi visualizza le strutture inserite può associare alla sua struttura un tot numero di ricette, ma deve poter visualizzare solo le ricette che non ha ancora associato.

Sei un grande e ti ringrazio infinitamente, questa cosa mi sta facendo impazzire :-)

Grazie mille
Guido

Klaus-zanini Profilo | Senior Member

L'obiettivo mio è risolverti il problema quindi se ci riesco sono più che felice

Dunque, se ho capito bene il concetto è: devo avere una query che mostri tutte le MIE ricette non ancora assegnate e quali delle MIE strutture possono essere usate per l'assegnazione, giusto?
Ad esempio:
- io inserisco le ricette 1 e 2 a nome mio e tu la 3 a nome tuo;
- io inserisco la struttura 10 a nome mio e tu la 20 a nome tuo;
- io associo la struttura 10 alla ricetta 1;
- La query quando mi collego io deve mostrarmi Ricetta 2 e Struttura 10
- La query quando ti colleghi tu deve mostrarti Ricetta 3 e struttura 20
Giusto?

Se è così penso ti manchi solo il "where" dell'utente dentro a T2 perché altrimenti il cross join ti estrae anche le strutture degli altri utenti.

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

zseven Profilo | Senior Member

Diciamo però che non ho bisogno di mostrare anche la struttura, in quanto io utente, quando effettuo il login, prima di tutto visualizzo la mia struttura.
Poi cliccando sul nome della struttura passo a visualizzare le ricette che la mia struttura non ha ancora associato, però a parte questo il concetto è esattamente come hai detto.

Purtroppo adesso non posso provarlo, stasera provo subito il codice e verifico.

Ti faccio sapere se è ok!
Grazie mille
Guido

Klaus-zanini Profilo | Senior Member

Ciao Guido,
penso che la query dovrebbe andare bene per il tuo scopo. Ti basterà aggiungere alla query nel "Where" globale l'Id_Struttura in cui ti trovi in quel momento e toglierlo dai campi della select.
Spero funzioni come vuoi tu, comunque fammi sapere

zseven Profilo | Senior Member

Ciao Klaus,
sembra essere perfetta così come l'hai scritta la query!

Sei stato gentilissimo e molto paziente :-)

P.S.
Come hai potuto vedere per quanto riguarda il linguaggio SQL ho ancora molte carenze sulle istruzioni un pò più complesse, anche soprattutto per quelle che con access non potevo utilizzare mentre con SQL SErver sì.
Sapresti per caso indicarmi qualche link o qualche bel libro di riferimento per approfondire?

Grazie mille di tutto
Guido

Klaus-zanini Profilo | Senior Member

Nessun problema do una mano volentieri come gli altri aiutano me.

Per i riferimenti a dire il vero non ho mai studiato su un libro. Io di solito imparo leggendo la guida in linea o l'MSDN.
Penso che i testi siano utili per infarinature, ma i casi reali come questi li risolvi solo con l'esperienza leggendo, chiedendo e provando
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-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5