Torna all'elenco degli articoli Articoli
Tempo di lettura: 20 minuti

9 esempi pratici di LEFT JOIN in SQL

LEFT JOIN è uno dei metodi più comuni di SQL. JOINs. Assicuratevi di conoscerne tutti i vantaggi e gli svantaggi esaminando tutti e nove i nostri esempi reali. LEFT JOIN esempi reali.

LEFT JOIN - accanto INNER JOIN - è uno degli strumenti SQL essenziali per lavorare con i dati di due o più tabelle. Ma come e quando si usa? Questi nove esempi di LEFT JOIN vi indicheranno la strada da seguire.

È la prima volta che sentite parlare di JOIN? Se è così, il nostro corso completo su SQL JOIN vi aiuterà a capire come funziona. Potrete imparare da zero tutti i tipi di SQL JOIN, i diversi modi di unire due o più tabelle e quando utilizzare ciascun tipo di JOIN. Imparerete anche ad auto-unire una tabella e a utilizzare join non equi. Alla fine del corso, avrete risolto 99 sfide interattive.

Le basi della LEFT JOIN

LEFT JOIN è uno dei diversi tipi di SQL JOINs. Lo scopo di JOINs è quello di ottenere i dati da due o più tabelle. LEFT JOIN raggiunge questo obiettivo restituendo tutti i dati della prima tabella (sinistra) e solo le righe corrispondenti della seconda tabella (destra). I valori non corrispondenti della tabella di destra saranno mostrati come NULL.

In che cosa si differenzia da altre JOIN? Ecco una breve panoramica, ma per una comprensione ancora migliore, date un'occhiata a questi esempi di SQL JOIN.

  • (INNER) JOIN - Restituisce solo le righe corrispondenti delle tabelle unite. Ecco un articolo per saperne di più sulle INNER JOIN.
  • RIGHT (OUTER) JOIN - Restituisce tutti i dati della tabella di destra e solo le righe corrispondenti della tabella di sinistra. I valori delle righe non corrispondenti saranno NULL.
  • FULL (OUTER) JOIN - Restituisce tutte le righe di entrambe le tabelle unite. Se ci sono righe non corrispondenti tra le tabelle, vengono mostrate come NULL. Per saperne di più, consultare l'articolo dedicato a FULL JOIN.
  • CROSS JOIN - Restituisce tutte le combinazioni di tutte le righe delle tabelle unite, ovvero un prodotto cartesiano. Maggiori informazioni sono disponibili nell'articolo CROSS JOIN.

Le parole tra parentesi nei nomi di JOIN non sono obbligatorie; SQL accetta sia la versione completa che quella breve.

Ciò significa che LEFT JOIN è uguale a LEFT OUTER JOIN. Quindi, sì, LEFT JOIN è un tipo di join esterno, insieme a RIGHT JOIN e FULL JOIN.

Come utenti di SQL, di solito scriviamo solo LEFT JOIN. Il motivo? È più breve e siamo pigri.

Per saperne di più, consultate l'articolo che spiega come funziona una LEFT JOIN.

Sintassi SQL LEFT JOIN

La sintassi di LEFT JOIN è la seguente.

SELECT …
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;

I due punti chiave sono la parola chiave LEFT JOIN e la clausola di unione ON. La prima tabella unita viene citata nella clausola FROM, quindi viene aggiunta la LEFT JOIN, seguita dalla seconda tabella che si desidera unire.

Le tabelle vengono unite in base alla corrispondenza dei valori delle colonne; si fa riferimento a queste colonne nella clausola ON e si mette un segno di uguale tra di esse. In questo modo si uniscono le tabelle in cui la colonna di una tabella è uguale alla colonna della seconda tabella. Questo è il tipo più comune di LEFT JOIN. È chiamato equi-join a causa del segno di uguale. È possibile utilizzare altri operatori di confronto; questi sono i join non equi ed esulano dallo scopo di questo articolo.

Tutto questo è spiegato anche nel nostro foglio informativo sulle JOIN di SQL. Tenetelo a portata di mano durante i seguenti esempi; vi aiuterà a comprenderli meglio.

Esempi di LEFT JOIN

Ora vi mostrerò alcuni esempi reali di utilizzo di LEFT JOIN. Inizierò con un esempio semplice e diretto per mostrare come funziona LEFT JOIN su dati reali.

Esempio 1: LEFT JOIN di base

Lavorerò con due tabelle. La prima è companyche contiene un elenco di aziende di elettronica. Utilizzare questo script per creare la tabella.

idcompany_name
1Lenovo
2Apple
3Samsung
4Huawei
5Fairphone

La seconda tabella è la tabella product tabella. Lo script per la creazione della tabella è qui.

idproduct_namecompany_id
1Fairphone 45
2Galaxy S24 Ultra3
3Galaxy Z Flip53
4iPhone 15 Pro2
5Fairbuds XL5
6MacBook Pro 16' M3 Pro2
7iPad Air 10.9' M12
8Galaxy Tab S9 FE+3

Si veda il sito LEFT JOIN per vedere che cosa succede:

SELECT company_name,
	 product_name
FROM company
LEFT JOIN product
ON company.id = product.company_id
ORDER BY company_name;

Seleziono l'azienda e il nome del prodotto. Queste sono le colonne di due tabelle. Quindi, devo unire le tabelle per ottenere queste colonne nell'output.

La tabella di sinistra è companye faccio riferimento ad essa in FROM. Poi aggiungo LEFT JOIN e la seconda tabella, che è product.

Nella clausola ON specifico le colonne su cui le tabelle saranno unite. In questo caso, si tratta della colonna id della prima e della colonna company_id della seconda tabella.

Ho usato ORDER BY per rendere l'output più leggibile. (Non è necessario ORDER BY perché l'unione funzioni).

A proposito di output, eccolo.

company_nameproduct_name
AppleiPhone 15 Pro
AppleiPad Air 10.9' M1
AppleMacBook Pro 16' M3 Pro
FairphoneFairphone 4
FairphoneFairbuds XL
HuaweiNULL
LenovoNULL
SamsungGalaxy Z Flip5
SamsungGalaxy S24 Ultra
SamsungGalaxy Tab S9 FE+

L'output mostra un elenco di tutte le aziende, in linea con LEFT JOIN che mostra tutti i dati della tabella di sinistra.

Quando un'azienda ha più prodotti, tutti i prodotti sono elencati e il nome dell'azienda è duplicato. Quando non ci sono prodotti dell'azienda (Huawei e Lenovo), il valore della colonna product_name è NULL.

Esempio 2: Un esempio di LEFT JOIN nella vita reale

Esploriamo uno scenario comune. In questo esempio, si vogliono elencare tutti i reparti e i loro dipendenti, ma anche mostrare i reparti senza dipendenti, se ce ne sono.

Per ottenere questo risultato, è necessario LEFT JOIN.

Ecco la tabella department e il suo script. È un elenco di reparti.

iddepartment_name
1Sales
2Accounting
3IT
4HR
5Operations

La seconda tabella è employee, che è un elenco di dipendenti. Ecco il suo script.

idfirst_namelast_namedepartment_id
1BobEstevez3
2FrancescaGotze2
3FrankGordon2
4MilicentJohnson3
5HansHandkeNULL
6KatieKeaton1
7LucaDi FrancescoNULL
8ZoeJong1
9PatrickRose2
10BillieThompsonNULL

I valori NULL indicano che a questo dipendente non è ancora stato assegnato un reparto.

Per mostrare i reparti e i loro dipendenti, nonché i reparti senza dipendenti, il codice è questo:

SELECT department.id AS department_id,
	 department_name,
	 employee.id AS employee_id,
       first_name,
       last_name	   
FROM department
LEFT JOIN employee
ON department.id = employee.department_id
ORDER BY department_id, employee_id;

Seleziono l'ID dalla tabella department e lo rinomino come department_id. La seconda colonna selezionata dalla stessa tabella è department_name. I dati selezionati dalla tabella employee sono la colonna id (rinominata employee_id) e i nomi dei dipendenti. Tutta questa ridenominazione delle colonne serve solo a rendere l'output più facile da leggere.

Ora, posso fare riferimento alla tabella department in FROM e LEFT JOIN con la tabella employee. Le tabelle vengono unite quando gli ID dei reparti sono uguali.

Infine, ordino il risultato in base al reparto e poi all'ID del dipendente per renderlo più leggibile. Ecco il risultato:

department_iddepartment_nameemployee_idfirst_namelast_name
1Sales6KatieKeaton
1Sales8ZoeJong
2Accounting2FrancescaGotze
2Accounting3FrankGordon
2Accounting9PatrickRose
3IT1BobEstevez
3IT4MilicentJohnson
4HRNULLNULLNULL
5OperationsNULLNULLNULL

L'output mostra tutti i reparti e i loro dipendenti. Mostra anche due reparti che non hanno dipendenti: Risorse umane e Operazioni. È possibile che il database non sia ancora stato aggiornato e che i nuovi dipendenti non siano stati assegnati al reparto.

Esempio 3: Un altro esempio di LEFT JOIN nella vita reale

Un altro esempio tipico di LEFT JOIN è quello in cui si vogliono trovare tutti i clienti e i loro ordini, ma si vogliono anche includere i clienti che non hanno ancora effettuato alcun ordine.

Per questo esempio, utilizzerò il seguente set di dati. La prima tabella è customerche è un semplice elenco di clienti. Ecco lo script.

idfirst_namelast_name
1FlorentinusGlöckner
2EmanAdcock
3ErikNyman
4LeebaKubo
5LiasVámos
6LavanyaNikolaev
7RishiPetit
8ChristieFodor
9AndrisLončar
10JulianaHarlan

La seconda tabella del set di dati è orders. È possibile crearla da soli utilizzando questo script.

Ecco come scrivo il codice per ottenere il risultato desiderato:

SELECT customer.first_name, 
       customer.last_name,
	 orders.id AS order_id,
	 orders.order_date
FROM customer
LEFT JOIN orders
ON customer.id = orders.customer_id;

Seleziono i nomi dei clienti dalla tabella customer. Logicamente, le informazioni sugli ordini provengono dalla tabella orders.

La tabella di sinistra è customere voglio tutte le sue righe. La LEFT JOIN con la tabella orders sull'ID del cliente.

L'output appare come questo:

first_namelast_nameorder_idorder_date
LiasVámos12024-01-01
EmanAdcock22024-01-08
ChristieFodor32024-01-08
AndrisLončar42024-01-12
LiasVámos52024-01-18
LavanyaNikolaev62024-01-22
JulianaHarlanNULLNULL
LeebaKuboNULLNULL
FlorentinusGlöcknerNULLNULL
ErikNymanNULLNULL
RishiPetitNULLNULL

Si può notare che mostra tutti i clienti e i loro ordini. Dove il cliente non ha ordini, c'è NULL.

Per fare più pratica, date un'occhiata a questo articolo che mostra altri quattro esempi di LEFT JOIN.

Esempio 4: LEFT JOIN con 3 tabelle

Questo è un esempio di LEFT JOIN in cui vi mostrerò come unire tre tabelle.

Diamo innanzitutto un'occhiata al set di dati.

La prima tabella è writercon lo script qui. È semplicemente un elenco di scrittori.

idfirst_namelast_name
1BernardineEvaristo
2AlbertCamus
3GeorgeOrwell
4ÉmileZola
5MilanKundera
6CharlesDickens
7BohumilHrabal
8WitoldGombrowicz

La seconda tabella è translator. È un elenco di traduttori di libri. Lo script per creare la tabella è qui.

idfirst_namelast_name
1JenniferCroft
2PeterConstantine
3EwaldOsers

L'ultima tabella è quella dei libri, che mostra informazioni sui libri in particolare. Ecco lo script.

idbook_titlepublication_yearwriter_idtranslator_id
1The Plague200823
2Cosmos201581
3Manifesto: On Never Giving Up20211NULL
4Girl, Woman, Other20191NULL
5The Stranger202223
6Germinal201243
7198420203NULL

Se il valore della colonna translator_id è NULL, il libro non è una traduzione.

In questo esempio, voglio mostrare tutti gli scrittori, indipendentemente dal fatto che abbiano o meno un libro. Voglio anche mostrare le informazioni sul traduttore del libro.

Ecco come dovrebbe essere il codice:

SELECT writer.first_name AS writer_first_name,
	 writer.last_name AS writer_last_name,
	 book_title,
	 translator.first_name AS translator_first_name,
	 translator.last_name AS translator_last_name
FROM writer
LEFT JOIN book
ON writer.id = book.writer_id
LEFT JOIN translator
ON book.translator_id = translator.id;

Seleziono i nomi degli scrittori, i titoli dei loro libri e i nomi dei traduttori. Per ottenere tutti questi dati, devo unire le tre tabelle.

L'unione di tre (o più) tabelle avviene sotto forma di catena. Dopo aver unito le prime due tabelle, si aggiunge un'altra join, si fa riferimento alla terza tabella e si dichiara la condizione di unione nella seconda clausola ON.

Per prima cosa, faccio riferimento alla tabella writere LEFT JOIN con la tabella book sullo scrittore ID.

Quindi, aggiungo la seconda clausola LEFT JOIN. La uso per unire la seconda tabella (book) con la tabella translator sull'ID del traduttore.

Perché queste LEFT JOINsono il risultato della relazione tra le tabelle? Il primo LEFT JOIN è presente perché potrebbero esserci scrittori senza libro. Tuttavia, questo vale anche per la relazione tra le tabelle book e translator: un libro può essere o non essere una traduzione, quindi può avere o non avere un traduttore corrispondente. Quindi, è necessario utilizzare anche LEFT JOIN tra di loro, perché si vuole mostrare i libri indipendentemente dal fatto che siano o meno traduzioni.

Ecco il risultato del codice:

writer_first_namewriter_last_namebook_titletranslator_first_nametranslator_last_name
AlbertCamusThe PlagueEwaldOsers
WitoldGombrowiczCosmosJenniferCroft
BernardineEvaristoManifesto: On Never Giving UpNULLNULL
BernardineEvaristoGirl, Woman, OtherNULLNULL
AlbertCamusThe StrangerEwaldOsers
ÉmileZolaGerminalEwaldOsers
GeorgeOrwell1984NULLNULL
MilanKunderaNULLNULLNULL
CharlesDickensNULLNULLNULL
BohumilHrabalNULLNULLNULL

Come si può vedere, i libri di Bernardine Evaristo vengono mostrati nonostante non siano traduzioni. Questo perché ho usato LEFT JOIN come secondo join.

Inoltre, Milan Kundera, Charles Dickens e Bohumil Hrabal sono mostrati nonostante non abbiano alcun libro e, quindi, alcun traduttore.

Esempio 5: LEFT JOIN 'forzata' con tre tabelle

Di solito la scelta di LEFT JOIN deriva dalla natura delle relazioni tra le tabelle. Tuttavia, a volte siamo "costretti" a usare LEFT JOIN. Vedrete presto cosa intendo.

La prima tabella del dataset è un elenco di amministratori denominati director. Ecco lo script.

idfirst_namelast_name
1StanleyKubrick
2CélineSciamma
3WoodyAllen
4LynneRamsay
5KrzysztofKieślowski

Segue la tabella streaming_platformche è un elenco di piattaforme di streaming disponibili. È possibile creare la tabella utilizzando questo script.

idplatform_name
1Netflix
2HBO
3Hulu
4Mubi
5Apple TV

La terza tabella è streaming_catalogue. Contiene informazioni sui film e ha relazioni con le prime due tabelle tramite director_id e streaming_platform_id. Ecco lo script per creare la tabella.

idmovie_titlerelease_yeardirector_idstreaming_platform_idstarted_showingended_showing
1Three Colours: Blue1993542023-02-282023-09-30
2Three Colours: White1994542023-02-282023-09-30
3Three Colours: Red1994542023-02-282023-09-30
4Manhattan Murder Mystery1993312023-08-15NULL
5Portrait of a Lady on Fire2019212023-01-012023-09-28
6Three Colours: Blue1993522024-01-15NULL
7Three Colours: White1994522024-01-15NULL
8Three Colours: Red1994522024-01-15NULL
9Tomboy2011212020-04-012021-04-01
10Vicky Cristina Barcelona2008312023-10-01NULL

I valori NULL nella colonna ended_showing significano che il film è ancora in programmazione sulla piattaforma.

Voglio mostrare tutti i registi, i loro film e le piattaforme di streaming che stanno proiettando (o hanno proiettato) i loro film. Inoltre, voglio mostrare i registi che non hanno alcun film in streaming.

La relazione tra le tabelle è che ogni film deve avere un regista, ma non viceversa. Inoltre, ogni film del catalogo deve avere una piattaforma di streaming, ma non tutte le piattaforme di streaming devono essere presenti nel catalogo.

Inizio a scrivere il codice selezionando i nomi dei registi, i titoli dei film, i nomi delle piattaforme e le date di inizio e fine proiezione.

Dagli esempi precedenti, si sa che si prevede di unire la tabella director con la tabella streaming_catalogue sulla colonna ID regista. Questo è ciò che faccio per assicurarmi di mostrare anche i registi che non hanno film in catalogo.

Ora aggiungo il secondo LEFT JOIN per unire la tabella streaming_catalogue con la tabella streaming_platform sulla base dell'ID della piattaforma.

SELECT first_name AS director_first_name,
	 last_name AS director_last_name,
	 movie_title,
	 platform_name,
	 started_showing, 
	 ended_showing
FROM director
LEFT JOIN streaming_catalogue
ON director.id = streaming_catalogue.director_id
LEFT JOIN streaming_platform
ON streaming_catalogue.streaming_platform_id = streaming_platform.id;

La query restituisce questo risultato:

director_first_namedirector_last_namemovie_titleplatform_namestarted_showingended_showing
KrzysztofKieślowskiThree Colours: BlueMubi2023-02-282023-09-30
KrzysztofKieślowskiThree Colours: WhiteMubi2023-02-282023-09-30
KrzysztofKieślowskiThree Colours: RedMubi2023-02-282023-09-30
WoodyAllenManhattan Murder MysteryNetflix2023-08-15NULL
CélineSciammaPortrait of a Lady on FireNetflix2023-01-012023-09-28
KrzysztofKieślowskiThree Colours: BlueHBO2024-01-15NULL
KrzysztofKieślowskiThree Colours: WhiteHBO2024-01-15NULL
KrzysztofKieślowskiThree Colours: RedHBO2024-01-15NULL
CélineSciammaTomboyNetflix2020-04-012021-04-01
WoodyAllenVicky Cristina BarcelonaNetflix2023-10-01NULL
LynneRamsayNULLNULLNULLNULL
StanleyKubrickNULLNULLNULLNULL

L'output mostra tutti i registi, i loro film e le piattaforme in cui sono o sono stati proiettati.

I film con tutti i dati tranne un NULL nelle colonne ended_showing possono ancora essere visti su una particolare piattaforma.

Nonostante non ci siano film nel catalogo, sono elencati anche Lynne Ramsay e Stanley Kubrick. Questo si riconosce dal fatto che hanno i loro nomi ma nessun altro dato.

Sono riuscito a trovarli perché ho usato due LEFT JOINs. Il primo LEFT JOIN non è discutibile; ho dovuto usarlo nel caso in cui ci fossero registi senza film. È risultato che ci sono.

Ma che dire del secondo LEFT JOIN? Sono stato in un certo senso costretto a usarlo per conservare tutti quei registi senza film e ottenere il risultato desiderato. Perché 'costretto'? Beh, usiamo INNER JOIN al posto del secondo LEFT JOIN, e vedrete.

SELECT first_name AS director_first_name,
	 last_name AS director_last_name,
	 movie_title,
	 platform_name,
	 started_showing, 
	 ended_showing
FROM director
LEFT JOIN streaming_catalogue
ON director.id = streaming_catalogue.director_id
JOIN streaming_platform
ON streaming_catalogue.streaming_platform_id = streaming_platform.id;

Nell'output mancano Lynne Ramsay e Stanley Kubrick!

director_first_namedirector_last_namemovie_titleplatform_namestarted_showingended_showing
KrzysztofKieślowskiThree Colours: BlueMubi2023-02-282023-09-30
KrzysztofKieślowskiThree Colours: WhiteMubi2023-02-282023-09-30
KrzysztofKieślowskiThree Colours: RedMubi2023-02-282023-09-30
WoodyAllenManhattan Murder MysteryNetflix2023-08-15NULL
CélineSciammaPortrait of a Lady on FireNetflix2023-01-012023-09-28
KrzysztofKieślowskiThree Colours: BlueHBO2024-01-15NULL
KrzysztofKieślowskiThree Colours: WhiteHBO2024-01-15NULL
KrzysztofKieślowskiThree Colours: RedHBO2024-01-15NULL
CélineSciammaTomboyNetflix2020-04-012021-04-01
WoodyAllenVicky Cristina BarcelonaNetflix2023-10-01NULL

Perché? Perché INNER JOIN restituisce solo le righe corrispondenti delle tabelle unite. Quindi, sono riuscito a produrre i registi senza i film con il primo LEFT JOIN. Ben fatto!

Ma poi ho usato INNER JOIN e ho incasinato tutto! INNER JOIN annulla il primo LEFT JOIN, poiché mostrerà solo le righe corrispondenti tra streaming_catalogue e streaming_platform.

Poiché Lynne Ramsay e Stanley Kubrick non hanno film nella tabella streaming_cataloguei loro film inesistenti non possono essere inseriti nella tabella e non appaiono nella tabella streaming_platform e non appaiono nel risultato finale.

Ecco un articolo che fornisce ulteriori suggerimenti ed esempi per la giunzione a sinistra di più tabelle.

Esempio 6: LEFT JOIN con DOVE

Continuiamo gli esempi di SQL LEFT JOIN utilizzando gli stessi dati del precedente.

Questo esempio mostra come LEFT JOIN possa essere utilizzato con la clausola WHERE.

Il codice qui sotto fa esattamente questo per trovare i registi, i loro film e le date di inizio e fine delle proiezioni. Tuttavia, non mostra tutti i film, ma solo quelli la cui proiezione è terminata prima del 1° ottobre 2023.

SELECT first_name,
	 last_name,
	 movie_title, 
	 started_showing, 
	 ended_showing
FROM director
LEFT JOIN streaming_catalogue
ON director.id = streaming_catalogue.director_id
WHERE ended_showing < '2023_10_01';

Dopo aver selezionato le colonne necessarie, ho creato la tabella LEFT JOIN director con la tabella streaming_ catalogo. Le tabelle sono unite dall'ID del regista.

Uso la clausola WHERE per produrre solo i film che hanno terminato la proiezione prima del 1° ottobre 2023. In WHERE confronto la colonna ended_showing con la data limite richiesta utilizzando l'operatore di confronto "meno di" (<).

Ecco l'output. Nessun film ha terminato la proiezione dopo il 1° ottobre 2023.

first_namelast_namemovie_titlestarted_showingended_showing
KrzysztofKieślowskiThree Colours: Blue2023-02-282023-09-30
KrzysztofKieślowskiThree Colours: White2023-02-282023-09-30
KrzysztofKieślowskiThree Colours: Red2023-02-282023-09-30
CélineSciammaPortrait of a Lady on Fire2023-01-012023-09-28
CélineSciammaTomboy2020-04-012021-04-01

Esempio 7: WHERE vs. ON in LEFT JOIN

Ora vi mostrerò come l'effetto di LEFT JOIN può essere annullato se WHERE viene utilizzato nella tabella di destra. E, naturalmente, vi mostrerò un rimedio.

Utilizzerò di nuovo lo stesso set di dati dell'esempio precedente. Supponiamo di voler fare una query per recuperare tutti i registi, indipendentemente dal fatto che abbiano o meno un film nel database. Per i registi che hanno un film, voglio mostrare solo i film usciti nel 1993.

Potrei provare a ottenere questo risultato scrivendo questa query:

SELECT DISTINCT first_name,
	   	    last_name,
	   	    movie_title, 
	   	    release_year
FROM director
LEFT JOIN streaming_catalogue
ON director.id = streaming_catalogue.director_id
WHERE release_year = 1993;

Innanzitutto, seleziono le colonne necessarie. Uso SELECT DISTINCT per evitare la duplicazione delle righe, dato che ci sono alcuni film che compaiono più di una volta nella tabella streaming_catalogue.

Ora, LEFT JOIN la tabella director con streaming_catalogue sull'ID del regista.

Il passo finale sarebbe quello di utilizzare la clausola WHERE e recuperare solo i film usciti nel 1993.

Vediamo l'output:

first_namelast_namemovie_titlerelease_year
KrzysztofKieślowskiThree Colours: Blue1993
WoodyAllenManhattan Murder Mystery1993

No, non è corretto! Ho ottenuto solo due registi invece di cinque. Ricordate che volevo un elenco di tutti i registi. Perché è successo questo, nonostante abbia usato LEFT JOIN?

Il motivo è che quando il filtro di WHERE viene applicato ai dati della tabella di destra, annulla l'effetto di LEFT JOIN. Ricordate che se il regista non ha film nella tabella, i valori della colonna release_year saranno NULL. È il risultato di LEFT JOIN. E il filtro in WHERE escluderà anche NULLdall'output.

Come si fa quindi a elencare tutti i direttori e a utilizzare contemporaneamente il filtro sull'anno di pubblicazione? La risposta è che bisogna spostare la condizione di filtraggio da WHERE a ON, in questo modo.

SELECT DISTINCT first_name,
	          last_name,
	          movie_title, 
	          release_year
FROM director
LEFT JOIN streaming_catalogue
ON director.id = streaming_catalogue.director_id AND release_year = 1993;

La condizione sull'anno di rilascio diventa ora la seconda condizione di unione nella clausola ON. La seconda (terza, quarta...) condizione viene aggiunta usando la parola chiave AND.

L'output è ora corretto:

first_namelast_namemovie_titlerelease_year
StanleyKubrickNULLNULL
LynneRamsayNULLNULL
CélineSciammaNULLNULL
KrzysztofKieślowskiThree Colours: Blue1993
WoodyAllenManhattan Murder Mystery1993

Potete saperne di più in questo articolo dedicato alla differenza tra WHERE e ON in SQL JOIN.

Esempio 8: LEFT JOIN con alias

In tutti gli esempi precedenti, l'uso di alias con le tabelle in LEFT JOIN non era necessario. Avrebbe potuto aiutare ad abbreviare i nomi delle tabelle e a scrivere il codice un po' più velocemente. Utile, sì, ma non obbligatorio.

Tuttavia, gli alias diventano obbligatori quando la tabella LEFT JOINING viene unita a se stessa, cioè quando si effettua un'auto-giunzione della tabella.

Vediamo come funziona in un esempio in cui voglio recuperare i nomi di tutti i dipendenti e i nomi dei loro manager. Voglio che questo elenco contenga i dipendenti che non hanno un manager superiore.

Lo dimostrerò nella tabella denominata employees_managers. Ecco lo script:

idfirst_namelast_namemanager_id
1LindKaiser2
2IanMcKune8
3DeckTrustrieNULL
4RupertaNind1
5GarrotCharsleyNULL
6AtheneFedoronko8
7PriscillaCrocombeNULL
8StafaniSidebottom8
9MarveTrustie1
10AntonyMarple2

Questo è un elenco di dipendenti. La colonna manager_id contiene l'ID del dipendente che è il manager di quel particolare dipendente. Alcuni dipendenti non hanno un manager, quindi il valore è NULL.

Per completare l'operazione richiesta, devo scrivere questa query:

SELECT e.first_name AS employee_first_name, 
	 e.last_name AS employee_last_name, 
	 m.first_name AS manager_first_name,
	 m.last_name AS manager_last_name
FROM employees_managers e
LEFT JOIN employees_managers m
ON e.manager_id = m.id;

Faccio riferimento alla tabella nella clausola FROM e le attribuisco l'alias e. Questa tabella servirà per i dati dei dipendenti.

Poi, faccio riferimento alla stessa tabella in LEFT JOIN e le attribuisco l'alias m. Verrà utilizzata per i dati dei manager.

In questo modo, ho potuto unire la tabella con se stessa. Non è diverso dall'unione di due tabelle diverse. Quando si esegue un'auto-giunzione, una tabella agisce come due tabelle. È sufficiente assegnare loro degli alias in modo che SQL sappia a quale tabella ci si riferisce.

La tabella è auto-unita dove l'ID del manager dalla tabella 'employee' è uguale all'ID del dipendente dalla tabella 'manager'. In questo modo, otterrò tutti i dipendenti e i loro manager.

Ora che le tabelle sono pronte, devo solo selezionare le colonne necessarie. Anche in questo caso, per fare una distinzione, utilizzo alias di tabella diversi per ottenere i nomi dei dipendenti e dei manager.

Ecco l'output:

employee_first_nameemployee_last_namemanager_first_namemanager_last_name
LindKaiserIanMcKune
IanMcKuneStafaniSidebottom
DeckTrustrieNULLNULL
RupertaNindLindKaiser
GarrotCharsleyNULLNULL
AtheneFedoronkoStafaniSidebottom
PriscillaCrocombeNULLNULL
StafaniSidebottomStafaniSidebottom
MarveTrustieLindKaiser
AntonyMarpleIanMcKune

Come si può vedere, si tratta di un elenco completo dei dipendenti e dei loro manager. Deck Trustrie, Garrot Charsley e Priscilla Crocombe non hanno manager. Sono al vertice della struttura gerarchica dell'azienda.

Esempio 9: LEFT JOIN con GROUP BY

Torniamo ora all'esempio 2, dove abbiamo lavorato con un elenco di reparti e dipendenti.

Un esempio semplice di LEFT JOIN con GROUP BY sarebbe quello di elencare tutti i reparti e contare il numero di dipendenti in ognuno di essi:

SELECT department_name,
	 COUNT(employee.id) AS number_of_employees
FROM department
LEFT JOIN employee
ON department.id = employee.department_id
GROUP BY department_name;

Seleziono il reparto e utilizzo la funzione aggregata COUNT() sulla colonna ID dipendente per trovare il numero di dipendenti.

I dati provengono da due tabelle. Ho bisogno di LEFT JOIN la tabella department con la tabella employee poiché voglio anche i reparti senza dipendenti. Le tabelle sono unite in base all'ID del reparto.

Poiché ho utilizzato una funzione aggregata, devo anche raggruppare i dati. Lo faccio utilizzando la clausola GROUP BY. Raggruppando l'output in base al nome del reparto, si otterrà il numero di dipendenti per ogni reparto.

Date un'occhiata. Bello, vero?

department_namenumber_of_employees
Accounting3
Operations0
Sales2
IT2
HR0

Ora proviamo un altro esempio e usiamo COUNT(*) invece di applicare COUNT() a una particolare colonna.

Questa volta, utilizzerò i dati relativi alle aziende e ai loro prodotti dell'Esempio 1. In questo esempio, voglio recuperare i dati relativi alle aziende e ai loro prodotti. In questo esempio, voglio recuperare tutte le aziende e mostrare il numero di prodotti che hanno.

Vediamo cosa succede se utilizzo COUNT(*):

SELECT company_name,
	 COUNT(*) AS number_of_products
FROM company
LEFT JOIN product
ON company.id = product.company_id
GROUP BY company_name;

Le tabelle azienda e prodotto sono LEFT JOINe si basano sull'ID dell'azienda. Uso COUNT(*) e GROUP BY per trovare il numero di prodotti per azienda.

Questo è l'output:

company_namenumber_of_products
Huawei1
Lenovo1
Samsung3
Apple3
Fairphone2

Tuttavia, posso dire che questo risultato non è corretto: Huawei e Lenovo avrebbero dovuto avere zero prodotti. Perché si è verificato questo errore?

Il colpevole è COUNT(*)! L'asterisco nella funzione COUNT() significa che conta tutte le righe, comprese quelle di NULL. È più chiaro ora? Sì, è vero: quando le aziende senza prodotti sono LEFT JOIN, avranno prodotti NULL. Tuttavia, si tratta comunque di un valore e COUNT(*) vedrà ogni valore di NULL come un prodotto. In altre parole, anche le aziende senza prodotti saranno mostrate come se avessero un prodotto.

Per risolvere questo problema, utilizzare COUNT(expression). In questo caso, significa COUNT(product.id). L'uso di COUNT() con un nome di colonna ignora NULL:

SELECT company_name,
	 COUNT(product.id) AS number_of_products
FROM company
LEFT JOIN product
ON company.id = product.company_id
GROUP BY company_name;

L'output è ora quello previsto:

company_namenumber_of_products
Huawei0
Lenovo0
Samsung3
Apple3
Fairphone2

Potete approfondire leggendo questo articolo sulle diverse varianti della funzione aggregata COUNT().

Altri esempi e risorse di LEFT JOIN SQL

Dagli esempi precedenti si può notare che LEFT JOIN ha un ampio utilizzo nel lavoro pratico con i dati. Può essere utilizzata per il semplice recupero dei dati, quando sono necessari tutti i dati di una tabella e solo quelli corrispondenti di un'altra. Tuttavia, può essere utilizzato anche per unire più tabelle, con WHERE, nelle self-join e con le funzioni aggregate e GROUP BY.

I join SQL sono fondamentali per lavorare con più tabelle, un'attività quotidiana anche per gli analisti di dati junior. Conoscere i join è un requisito indispensabile per potersi considerare esperti di SQL e migliorare nel proprio lavoro.

Ciò significa anche conoscere LEFT JOIN, poiché è uno dei due tipi di join più utilizzati. A causa delle sue caratteristiche molto specifiche, molti compiti non possono essere svolti se non sfruttando LEFT JOIN. Quindi, se avete bisogno di una guida approfondita su questi argomenti, vi invitiamo a dare un'occhiata al nostro corsoSQL JOIN .

Inoltre, è necessario mettere in pratica tutti questi concetti per farli assimilare. Ciò significa esercitarsi su LEFT JOIN e su altri tipi di JOIN, in modo da poterli distinguere. Potete provare queste 12 domande di esercitazione sulle JOIN o alcuni dei suggerimenti su come esercitarsi con SQL JOIN. Se avete in programma un colloquio di lavoro in SQL, provate a rispondere a queste 10 domande di SQL JOIN. Buon apprendimento!