Vai al contenuto
eLearner.app
Modulo 3 · Lezione 2 di 410/57 nel corso~10 min
Lezioni del modulo (2/4)

Tenere tutto a sinistra: LEFT JOIN

L'INNER JOIN della lezione precedente ha un effetto collaterale importante: scarta le righe senza corrispondenza. Se un dipendente non ha un dipartimento (department_id è NULL), sparisce dal risultato.

A volte questo è quello che vuoi. Spesso però no: in un report HR è fondamentale vedere tutti i dipendenti, anche quelli senza dipartimento, e sapere quali sono. Per questo esiste LEFT JOIN (per esteso LEFT OUTER JOIN).

Come funziona

SQL
SELECT colonne
FROM   tabella_a
LEFT JOIN tabella_b ON tabella_a.x = tabella_b.y;

Letta in italiano: "tieni tutte le righe di tabella_a; per ognuna prova ad accostarle una riga di tabella_b; se non c'è corrispondenza, riempi le colonne di tabella_b con NULL".

La parola chiave è LEFT: significa "tabella di sinistra", cioè quella scritta dopo FROM. Tutte le sue righe sopravvivono, sempre.

SQL
-- Tutti i dipendenti, anche quelli senza dipartimento:
SELECT e.first_name,
       e.last_name,
       d.name AS dipartimento
FROM   employees   AS e
LEFT JOIN departments AS d ON e.department_id = d.id;

Nel nostro dataset questa query restituisce 10 righe (un dipendente ciascuno). Andrea Costa, che ha department_id = NULL, compare con dipartimento = NULL invece di sparire.

Trovare i "senza corrispondenza"

Una conseguenza utilissima: filtrando per IS NULL sulla colonna della tabella di destra trovi proprio le righe senza match:

SQL
-- Dipendenti orfani: nessun dipartimento assegnato
SELECT e.first_name, e.last_name
FROM   employees   AS e
LEFT JOIN departments AS d ON e.department_id = d.id
WHERE  d.id IS NULL;

Questo trucco si usa spessissimo nel mondo reale: "trovami gli ordini senza cliente", "i prodotti senza recensioni", "gli utenti che non hanno mai fatto login".

Prova tu

Esercizio#sql.m3.l2.e1
Tentativi: 0Caricamento…

Restituisci nome (first_name) e cognome (last_name) dei dipendenti che NON hanno un dipartimento assegnato. Una o più righe, due colonne.

Caricamento editor…
Mostra suggerimento

Completa la WHERE con d.id IS NULL — vuoi le righe in cui il LEFT JOIN non ha trovato un dipartimento corrispondente.

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

Esercizio#sql.m3.l2.e2
Tentativi: 0Caricamento…

Elenca tutti i dipartimenti (departments.name) e accanto il numero di dipendenti, includendo anche i dipartimenti senza alcun dipendente (mostra 0 per quelli). Suggerimento: parti da departments e fai LEFT JOIN con employees, poi GROUP BY + COUNT.

Caricamento editor…
Mostra suggerimento

Usa COUNT(e.id) (non COUNT(*)) per contare 0 quando non c'è alcun match: COUNT(*) conterebbe 1 grazie alla riga LEFT JOIN con NULL.

Soluzione disponibile dopo 3 tentativi