È arrivato il momento di parlare della vita vera. Di quella parte che non puoi evitare: gli errori. Beccarli, correggerli e capirli — è una parte obbligatoria del lavoro con i dati. Vediamo insieme quali trappole ci aspettano quando lavoriamo con JOIN in SQL e come evitarle.
Errore 1: Mancanza della condizione di join — creazione del prodotto cartesiano
L'errore più comune è dimenticare di specificare la condizione di join usando ON. In questo caso ottieni un prodotto cartesiano, dove ogni riga della prima tabella viene combinata con ogni riga della seconda. Il risultato? Un sacco di righe senza senso che ti confondono solo di più.
Facciamo un esempio. Supponiamo di avere queste tabelle:
Studenti (students):
| student_id | nome |
|---|---|
| 1 | Otto |
| 2 | Anna |
Corsi (courses):
| course_id | nome_corso |
|---|---|
| 101 | Matematica |
| 102 | Storia |
Ora scriviamo una query dimenticando ON:
SELECT *
FROM students
JOIN courses;
Risultato:
| student_id | nome | course_id | nome_corso |
|---|---|---|---|
| 1 | Otto | 101 | Matematica |
| 1 | Otto | 102 | Storia |
| 2 | Anna | 101 | Matematica |
| 2 | Anna | 102 | Storia |
Non sembra giusto, vero? Questo incubo si chiama prodotto cartesiano.
Come risolvere: usa ON per specificare come sono collegati i dati tra le tabelle.
SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;
E qui nasce un nuovo capitolo di errori...
Protezione dal disastro
Questo problema è così comune che in PostgreSQL hanno vietato l'uso di JOIN senza ON e condizione.
Se vuoi davvero combinare ogni riga con ogni altra, puoi usare la sintassi senza JOIN:
SELECT *
FROM students, courses;
Un altro caso in cui JOIN senza ON funziona:
- Con
NATURAL JOIN— seleziona automaticamente le colonne con lo stesso nome. - Con
USING— specifichi la lista delle colonne su cui fare il join. CROSS JOIN— sempre senza condizione, è proprio il prodotto cartesiano.
Errore 2: Condizione di join sbagliata
A volte specifichi la condizione di join, ma la fai male. Per esempio, colleghi le tabelle su colonne che non c'entrano nulla tra loro.
Supponiamo di voler ottenere la lista degli studenti e dei corsi a cui sono iscritti, ma sbagliamo e facciamo il join su colonne non collegate:
SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;
Questa query darà un risultato sbagliato, perché student_id e course_id sono due cose completamente diverse.
Come risolvere: assicurati di usare le colonne giuste per il join. Un join corretto potrebbe essere così (se hai una tabella enrollments che collega studenti e corsi):
SELECT students.nome, courses.nome_corso
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;
Errore 3: Duplicazione delle righe nel risultato
Quando aggiungi più JOIN in una query, a volte questo porta a duplicare le righe. Succede se nelle tabelle ci sono dati ripetuti, oppure hai sbagliato le condizioni di join.
Supponiamo che lo studente Otto sia iscritto due volte allo stesso corso nella tabella enrollments.
Dati in enrollments:
| student_id | course_id |
|---|---|
| 1 | 101 |
| 1 | 101 |
Ora la query con JOIN darà questi risultati:
SELECT students.nome, courses.nome_corso
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;
Risultato:
| nome | nome_corso |
|---|---|
| Otto | Matematica |
| Otto | Matematica |
Come risolvere: prima di tutto, assicurati che nelle tue tabelle non ci siano dati duplicati. Se invece è il comportamento che ti aspetti, elimina i duplicati usando DISTINCT:
SELECT DISTINCT students.nome, courses.nome_corso
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;
Errore 4: Perdita di righe usando INNER JOIN
INNER JOIN restituisce solo le righe che hanno corrispondenza in entrambe le tabelle. Se in una tabella manca il valore corrispondente, la riga viene scartata. Puoi perdere dati se scegli il tipo di join sbagliato.
Supponiamo di avere uno studente che non è ancora iscritto a nessun corso:
Studenti (students):
| student_id | nome |
|---|---|
| 1 | Otto |
| 2 | Anna |
| 3 | Dhany |
Iscrizioni (enrollments):
| student_id | course_id |
|---|---|
| 1 | 101 |
| 2 | 102 |
Ora la query con INNER JOIN:
SELECT students.nome, courses.nome_corso
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;
Risultato:
| nome | nome_corso |
|---|---|
| Otto | Matematica |
| Anna | Storia |
E Dhany dov'è? Se vuoi includere anche gli studenti senza corsi, devi usare LEFT JOIN:
SELECT students.nome, courses.nome_corso
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id;
Errore 5: Gestione sbagliata dei valori NULL
Se in una delle tabelle ci sono righe con valori vuoti (NULL), queste potrebbero essere escluse dai risultati (ad esempio, quando usi condizioni di filtro).
Esempio: usi LEFT JOIN, ma poi aggiungi WHERE per filtrare.
SELECT students.nome, courses.nome_corso
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.nome_corso = 'Matematica';
Ora gli studenti senza corsi non saranno inclusi nel risultato, anche se hai usato LEFT JOIN.
Come risolvere: se vuoi includere anche le righe senza corsi, sostituisci WHERE con ON oppure aggiungi una condizione extra:
SELECT students.nome, courses.nome_corso
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.nome_corso IS NULL OR courses.nome_corso = 'Matematica';
Errore 6: Confusione tra i tipi di join
Ti confondi su quale tipo di join usare. Per esempio, usi RIGHT JOIN quando potresti semplicemente usare LEFT JOIN invertendo l'ordine delle tabelle.
Come evitare la confusione:
- Usa
LEFT JOINquando puoi. È più intuitivo. - Cambia l'ordine delle tabelle per evitare di dover usare
RIGHT JOIN.
GO TO FULL VERSION