Leçons du module (2/4)
Gestion des NULL : IS NULL et COALESCE
Dans le jeu de données employees, Andrea Costa est spécial : il a
department_id = NULL. Vous avez déjà frôlé NULL (avec
LEFT JOIN), mais il est temps de le prendre au sérieux : les NULL en SQL
se comporter différemment de toute autre valeur, et les ignorer est l'un des
principales causes de bogues dans le code de production.
NULL n'est pas zéro, ni une chaîne vide
NULL signifie valeur inconnue/manquante. Ce n'est pas 0, ni '', ni
false. C'est "Je ne sais pas". De là découle une propriété surprenante :
NULL n'est égal à rien, pas même à lui-même.
-- All these expressions return NULL (not true!):
SELECT NULL = NULL; -- NULL
SELECT NULL = 0; -- NULL
SELECT NULL <> 'qualcosa'; -- NULLConséquence concrète : WHERE column = NULL ne fonctionne jamais. Vous devez utiliser
les opérateurs dédiés IS NULL / IS NOT NULL :
-- Employees without a department:
SELECT first_name, last_name
FROM employees
WHERE department_id IS NULL;
-- Employees WITH a department:
SELECT first_name, last_name
FROM employees
WHERE department_id IS NOT NULL;COALESCE — la solution de repli NULL
Souvent, vous souhaitez afficher quelque chose au lieu de NULL lorsque les données sont
manquant : la chaîne '(none)', zéro, une date par défaut. La fonction qui
fait exactement cela est COALESCE(a, b, c, ...) : il renvoie le premier
argument non NULL dans la liste.
-- Show the department_id, or 0 if missing:
SELECT first_name, last_name, COALESCE(department_id, 0) AS dept
FROM employees;Combiné avec un LEFT JOIN, il devient incroyablement puissant pour les rapports :
SELECT e.first_name,
e.last_name,
COALESCE(d.name, '(nessun dipartimento)') AS dipartimento
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id;Résultat : tous les salariés sont revenus, avec le nom du service ou une mention explicite label pour ceux qui n’en ont pas.
NULL et agrégats
Les fonctions d'agrégation ignorent les NULL (sauf COUNT(*)) :
COUNT(department_id)ne compte que les lignes avec une valeur ;- La moyenne de
AVG(salary)ignore lesNULL— il ne les traite pas comme 0 ; SUM(...)additionne uniquement les valeurs non NULL.
C'est presque toujours ce que vous voulez. Mais il est bon à savoir : si vous êtes
en recherchant "le nombre total d'employés" utilisez COUNT(*), pas
COUNT(department_id).
Essayez-le
Pour chaque employé, affichez le prénom (first_name), le nom (last_name) et une colonne « dipartimento_id » qui est égale à leur Department_id ou -1 s'il n'est pas attribué. Trois colonnes, une ligne par employé.
Afficher l'indice
Utilisez COALESCE(department_id, -1) pour remplacer les valeurs NULL par -1.
Solution disponible après 3 tentatives
Exercice de révision
Renvoie le prénom (first_name), le nom (last_name) et le nom du service (departments.name) de TOUS les employés, en affichant « (nessuno) » lorsque le service est manquant. Utilisez LEFT JOIN + COALESCE.
Afficher l'indice
COALESCE(d.name, '(nessuno)') gère le NULL introduit par LEFT JOIN.
Solution disponible après 3 tentatives