Leçons du module (2/4)
Garder tout à gauche : LEFT JOIN
Le INNER JOIN de la leçon précédente a un effet secondaire important : il
supprime les lignes qui n'ont aucune correspondance. Si un employé n'a pas de département
(department_id est NULL), ils disparaissent du résultat.
Parfois, c'est ce que tu veux. Mais souvent, ce n'est pas le cas : dans un rapport RH
il est essentiel de voir tous les salariés, y compris ceux sans service,
et sachez qui ils sont. C'est à cela que sert LEFT JOIN (au complet, LEFT OUTER JOIN).
Comment ça marche
SELECT columns
FROM table_a
LEFT JOIN table_b ON table_a.x = table_b.y;Lire en anglais : "conserver toutes les lignes de table_a ; pour chacune d'elles, essayez de
attachez une ligne de table_b ; s'il n'y a pas de correspondance, remplissez les colonnes de
table_b avec NULL".
Le mot clé est LEFT : il signifie "table de gauche", c'est à dire celui écrit
après FROM. Toutes ses rangées survivent toujours.
-- 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;Dans notre ensemble de données, cette requête renvoie 10 lignes (un employé chacune). Andréa
Costa, qui a department_id = NULL, apparaît avec dipartimento = NULL
au lieu de disparaître.
Trouver les lignes "sans correspondance"
Une conséquence très utile : en filtrant avec IS NULL sur une colonne du
dans le tableau de droite, vous trouvez exactement les lignes sans correspondance :
-- 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;Cette astuce est utilisée tout le temps dans le monde réel : "trouvez-moi des commandes sans client", "produits sans avis", "utilisateurs qui ne se sont jamais connectés dans".
Essayez-le
Renvoie le prénom (first_name) et le nom (last_name) des employés auxquels aucun service n'est attribué. Une ou plusieurs lignes, deux colonnes.
Afficher l'indice
Complétez WHERE avec d.id IS NULL — vous voulez les lignes où LEFT JOIN n'a pas trouvé de département correspondant.
Solution disponible après 3 tentatives
Exercice de révision
Répertoriez tous les départements (departments.name) et à côté d'eux le nombre d'employés, y compris également les départements sans employés (montrez 0 pour ceux-ci). Astuce : commencez par les départements et effectuez un LEFT JOIN avec les employés, puis GROUP BY + COUNT.
Afficher l'indice
Utilisez COUNT(e.id) (et non COUNT(*)) pour compter 0 lorsqu'il n'y a pas de correspondance : COUNT(*) compterait 1 à cause de la ligne LEFT JOIN avec NULL.
Solution disponible après 3 tentatives