Newsgroup: it.comp.software.database
Titolo: JOIN complicata

Devo fare la join fra 2 tabelle in relazione 1:n, dove però la chiave
esterna usata può essere NULL!
In pratica.
  tbl1 (id, ..., chiave_est)
  tbl2 (id, ...)
dove l'associazione è tbl1.chiave_est <-> 
tbl2.id
.
Volendo fare la JOIN si scrive:
  SELECT * FROM tbl1, tbl2 WHERE tbl1.chiave_est = 
tbl2.id
ma questa dà più righe del previsto se, come detto, chiave_est è stata
definita come attributo che puà assumere NULL: come fare?
Ho provato con:
  SELECT * FROM tbl1, tbl2 WHERE tbl1.chiave_est = 
tbl2.id
 OR
tbl1.chiave_est IS NULL
ma anche questa è errata!
Sono 2 gg che ci penso sopra, ma non riesco a trovare una soluzione..
Mhaxx

 Mhaxx
Ciao
-- 
Luca Bianchi
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
http://italy.mvps.org


Devi usare una left join, ad es:
SELECT questo, quello FROM tbl1
LEFT JOIN tbl2 ON 
tbl2.id
 = tbl1.chiave_est;
(o invertendo le tabelle nella query, fai la prova)
Ciao
Matteo

coinvolte, alcuni record di prova ed il risultato che vuoi ottenere...
Ecco (MySQL):
CREATE TABLE sottoaree
  (codice SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
   nome VARCHAR(40) NOT NULL,
   PRIMARY KEY (codice))
CREATE TABLE argomenti
  (codice SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
   cod_sottoarea SMALLINT UNSIGNED,
   PRIMARY KEY (codice),
   FOREIGN KEY (cod_sottoarea) REFERENCES sottoaree ON DELETE CASCADE)
Faccio notare che non c'è il NOT NULL nell'attributo cod_sottoarea di
argomenti.
Io con una SELECT voglio ottenere tante righe quanti sono gli
argomenti, e oguno voglio corredarlo del *nome* della sottoarea. Nel
caso non esista (possibile visto che cod_sottoarea può essere NULL)
voglio che come nome gli venga associato per es. "", o NULL, è lo
stesso, ma l'importante è che ci sia.
Se faccio: SELECT * FROM argomenti, sottoaree WHERE
argomenti.cod_sottoarea = sottoaree.codice, ottengo non n righe (dove
n è il numero di righe di argomenti), ma n-m (dove m è il numero di
righe di argomenti con cod_sottoarea è NULL). Giusto?
Ebbene io voglio ottenerle tutte le n righe di argomenti, e per le m
righe che hanno cod_sottoarea NULL non mi interessa che codice e nome
di sottoaree venga associato, potrebbero essere  entrambi NULL.
Forse, se non ho capito male, risolverei il tutto con una LEFT JOIN,
può essere? In ogni caso, non capisco tutte queste JOIN (natural,
cross, etc).. quale corrisponde al modo in cui facevo io a manina le
JOIN (cioè usando il WHERE)? E soprattutto: se ho 3 tabelle,
sintatticamente come ne scrivo le JOIN?
Grazie 1000..
Mhaxx

 Grazie 1000..


WHERE condizione
No no, intedevo 3 tabelle legate così: tab1 <-> tab2 e tab2 <-> tab3.
Io ho provato una cosa del genere:
FROM libri JOIN trattadi ON libri.codice = trattadi.cod_libro,
trattadi JOIN argomenti ON trattadi.cod_libro = argomenti.codice
ma da errore!
Mhaxx

 ma da errore!
...sintatticamente è corretta o perlomeno sono io a non vedere errori...
dicci quale errore ti viene restituito e cercheremo di interpretarlo...


dicci quale errore ti viene restituito e cercheremo di interpretarlo...
Risolto tutto..
Grazie, ciao.
Mhaxx
P.S. qualche idea per il problema che ho postato sull'ORDER BY?

 P.S. qualche idea per il problema che ho postato sull'ORDER BY?
...non ho capito la tua esigenza...


>...non ho capito la tua esigenza...
Immagina una query del tipo:
SELECT B.cognome, B.nome, A.dato
FROM A JOIN B ON ...
GROUP BY B.cognome, B.nome
e un risultato come questo:
Bianchi Antonio 5
Bianchi Giulio 9
Rossi Andrea 5
Rossi Massimo 3
Rossi Silvio 9
Zulù Franco 5
Zulù Mario 3
Zulù Pino 9
Quello che mi serve è di questo risultato avere solo una riga per ogni
A.dato, cioè fare una specie di DISTINCT sul 3° campo, quello numerico
e ottenere così una riga per ogni A.dato. Il fatto è che se faccio la
DISTINCT, essa mi dà una riga a caso fra quelle di un certo A.dato, io
invece per ogni A.dato voglio la prima riga. In altre parole ho
bisogno di tenere, per tutte le righe di un certo A.dato, solo quella
che compare per prima nella precedente lista:
Bianchi Antonio 5
Bianchi Giulio 9
Rossi Massimo 3
Mi è stato suggerita una query, ma pare servano le subselect, che non
mi pare siano supportate da MySQL 4. Forse esiste una forma
equivalente o una query diversa che funziona lo stesso.. mah, io per
ora non sono ancora riuscito a costruirne una..
Mhaxx