Newsgroup: it.comp.software.database
Titolo: QUERY COMPLICATA

Cerco di spiegare il problema con un esempio pratico:
ho una tabella chiamata MENU con l'elenco delle voci di menu di un
programma, cosi' strutturata:
- idVoce (int, chiave primaria)
- Voce (varchar)
Poi ho una tabella che lega le voci di menu agli utenti, poiche' non tutti
gli utenti possono vedere tutti le voci di menu.
La tabella si chiama LEG_MENU_UTENTI ed e' cosi' strutturata:
- idVoce (int)
- NomeUtente (varchar(10))
la coppia idVoce e NomeUtente sono anche chiave primaria della tabella.
Adesso avrei bisogno di definire una query che, dato un utente, visualizzi
l'elenco di tutte le voci di menu della tabella MENU e specifichi se
l'utente e' autorizzato o meno a vedere il corrispondente menu.
Ad esempio, ipotizziamo che le voci di menu siano:
idVoce  - Voce
1         - setup
2         - analisi
3         - laboratori
4         - news
e che l'utente Rossi sia abilitato ad eseguire soltanto la voce 1 e la voce
3, quindi la tabella LEG_MENU_UTENTI abbia i seguenti record:
1 - Rossi
3 - Rossi
1 - Bianchi
2 - Bianchi
ecc....
La Query da definire dovrebbe fornire il seguente elenco:
1 - setup - true
2 - analisi - false
3 - laboratori - true
4 - news - false
Spero di essere stato chiaro.
Grazie
Paolo





la select per ROSSI e' la seguente:




select mm.IDVOCE, mm.VOCE, decode (tp.NOMEUTENTE, null, 'false', 'true')


from menu mm, (


        
SELECT m.IDVOCE, m.VOCE, l.NOMEUTENTE 


        
FROM MENU m, LEG_MENU_UTENTI l


        
where m.IDVOCE = l.IDVOCE


        
AND l.NOMEUTENTE = 'ROSSI' 


        
order by m.IDVOCE) tp


where mm.IDVOCE = tp.IDVOCE (+)




e restituisce i seguenti valori:




1-SETUP-true


2-ANALISI-false


3-LABORATORI-true


4-NEWS-false




la mia domanda e' un'altra se un giorno avrai due ROSSI che sono abilitati a fare cose diverse???






ciao


claudio







 l'utente e' autorizzato o meno a vedere il corrispondente menu.
Non hai specificato che database stai usando, comunque, cio' che
serve a te e' un outer join, che unisce tutti i record di una tabella
con i record che corrispondono dall'altra tabella.
Purtroppo ogni database ha il suo modo per definire una outer join,
alcuni non supportano per niente le outer join.
Con SQL Server la sintassi e'
SELECT... FROM <tabella1> LEFT JOIN <tabella2> ON campotabella1=campotabella2
mentre per Oracle e'
SELECT ... FROM <tabella1>,<tabella2> WHERE campotabella1 += campotabella2
Per avere la "decodifica" della voce in "true" o "false" puoi
usare la gia' citata DECODE in Oracle, mentre in SQL server usi
CASE <campo>
	WHEN <valore> THEN <valore da visualizzare>
	...
	ELSE <valore standard>
END
Davide

 ha scritto nel messaggio
news:9fnn3r$50re2$1...@ID-18487.news.dfncis.de...


 relazionale ???)
Un db relazionale deve supportare i join, ma non e' detto che supporti
gli OUTER join (e' la parola "outer" che frega).
Per esempio: PostGres non li supporta.
Benche' gli Outer Join siano specificato dallo standard SQL 92 molti
database hanno scelto di non implementare la funzione perche' provoca
molti problemi. In SQL Server ed Oracle gli O.J. possono essere realizzati
solo tra due tabelle e non puoi "concatenare" piu' O.J. usando delle View.
Se ci provi ottieni dei risultati anomali (record moltiplicati, record
che spariscono...).
Davide

Intanto grazie a tutti per le risposte che mi hanno permesso di trovare la
soluzione.
Ad ogni modo sapevo che dovevo utilizzare degli Outer Join ma il problema
era piu' complesso.
infatti la sintassi che ho dovuto utilizzare e' stata (avendo come db SQL
SERVER):
SELECT ....  FROM <tabella1> LEFT OUTER JOIN (SELECT .... FROM <tabella2>
WHERE (NomeUtente = 'ROSSI')) appoTabella ON <tabella1>.IDVoce =
appoTabella.IDVoce
praticamente un misto tra le soluzioni di Claudio di Gregorio e la soluzione
di dbianchi.
In pratica quello che non sapevo era che si puo' far riferimento ad una
(select ...) come fosse una tabella.
saluti
Paolo

 ha scritto nel messaggio
news:9fnp13$50re2$5...@ID-18487.news.dfncis.de...


 che differenza sostanziale c'č tra INNER JOIN e OUTER JOIN ?
Una Inner Join ritorna solo i record che "corrispondono" al
collegamento, se nessun record della tabella "A" ha un'equivalente
nella tabella "B", nessun record verra' ritornato.
Una Outer Join ritorna sempre *tutti* i record di una tabella ed i
soli record che corrispondono dell'altra tabella. Nei casi in cui 
non c'e' una corrispondenza i campi della seconda tabella sono NULL.
Inner Join:
	select tab1.campo, tab2.campo from tab1, tab2 where
		tab1.campid=tab2.campoid
Outer Join:
	sql server;
		select tab1.campo, tab2.campo from
			tab1 left join tab2 on
				tab1.campoid=tab2.campoid
	oracle:
		select tab1.campo, tab2.campo from
			tab1, tab2 where
			tab1.campoid+=tab2.campoid
Nota: la sintassi consigliata da SQL 92 e' quella di SQL Server.
Davide

 ha scritto nel messaggio
news:9fnv6m$50re2$1...@ID-18487.news.dfncis.de...
