Lecții din modul (2/4)
Păstrând totul în stânga: LEFT JOIN
INNER JOIN din lecția anterioară are un efect secundar important: acesta
elimină rânduri care nu se potrivesc. Dacă un angajat nu are departament
(department_id este NULL), acestea dispar din rezultat.
Uneori asta vrei. De multe ori, însă, nu este: într-un raport de resurse umane
este esențial să vezi toți angajații, inclusiv cei fără departament,
si stiu cine sunt. Pentru asta este LEFT JOIN (în întregime, LEFT OUTER JOIN).
Cum funcționează
SELECT columns
FROM table_a
LEFT JOIN table_b ON table_a.x = table_b.y;Citiți în engleză: "păstrați toate rândurile de table_a; pentru fiecare încercați să
atașați un rând din table_b; dacă nu există potriviri, completați coloanele din
table_b cu NULL".
Cuvântul cheie este LEFT: înseamnă „masa din stânga”, adică cel scris
după FROM. Toate rândurile sale supraviețuiesc, întotdeauna.
-- All employees, including those without a department:
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;În setul nostru de date, această interogare returnează 10 rânduri (un angajat fiecare). Andrea
Costa, care are department_id = NULL, apare cu dipartimento = NULL
în loc să dispară.
Găsirea rândurilor „fără potrivire”.
O consecință foarte utilă: prin filtrarea cu IS NULL pe o coloană a
tabelul din dreapta găsiți exact rândurile fără potrivire:
-- Orphan employees: no department assigned
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;Acest truc este folosit tot timpul în lumea reală: "găsește-mi comenzi cu nr client", "produse fără recenzii", "utilizatori care nu s-au conectat niciodată în".
Încearcă
Returnează prenumele (prenume) și numele (numele) angajaților care NU au un departament alocat. Unul sau mai multe rânduri, două coloane.
Afișează indiciu
Completați WHERE cu d.id IS NULL — doriți rândurile în care LEFT JOIN nu a găsit un departament potrivit.
Soluție disponibilă după 3 încercări
Exercițiu de revizuire
Listați toate departamentele (departments.name) și lângă ele numărul de angajați, inclusiv departamentele fără angajați (afișați 0 pentru aceștia). Sugestie: începeți de la departamente și faceți un LEFT JOIN cu angajații, apoi GROUP BY + COUNT.
Afișează indiciu
Utilizați COUNT(e.id) (nu COUNT(*)) pentru a număra 0 când nu există nicio potrivire: COUNT(*) va conta 1 din cauza rândului LEFT JOIN cu NULL.
Soluție disponibilă după 3 încercări