Petit rappel : les fonctions d’agrégation, c’est celles qui bossent direct avec plusieurs lignes de données et te renvoient un seul résultat. Sous PostgreSQL, tu vas souvent utiliser ces fonctions d’agrégation :
SUM()— additionner des données.AVG()— calculer la moyenne.MIN()— trouver la valeur minimale.MAX()— trouver la valeur maximale.COUNT()— compter les lignes.
À première vue, c’est simple : tu passes une colonne ou une expression à la fonction, et tu récupères le résultat. Mais qu’est-ce qui se passe si tu tombes sur un NULL dans la colonne ?
Comportement de NULL dans les agrégats : petit résumé
C’est là que ça devient intéressant :
SUM()etAVG()ignorent lesNULL. Si au moins une ligne a une valeurNULL, elle ne sera juste pas prise en compte dans les calculs. Logique, non ? Comment la somme pourrait-elle augmenter si quelqu’un “n’est pas venu à la fête” ? Et pour la moyenne, si une valeur manque, on ne la compte pas non plus.MIN()etMAX()zappent aussi lesNULL. Elles cherchent la valeur min ou max uniquement parmi les données qui ne sont pasNULL. Donc, si tu cherches l’employé le plus jeune et qu’il a oublié de remplir sa date de naissance,NULLne sera pas le gagnant.COUNT(*)compte toutes les lignes, même celles où il y a unNULL. Par contre,COUNT(colonne)ne compte que les lignes où la colonne a une valeur, doncNULLest ignoré.
On va voir ça avec des exemples.
Exemples d’utilisation des fonctions d’agrégation avec NULL
Voici la table students_scores, qui contient les notes des étudiants pour un test :
| student_id | name | score |
|---|---|---|
| 1 | Alisa | 85 |
| 2 | Bob | NULL |
| 3 | Charlie | 92 |
| 4 | Dana | NULL |
| 5 | Elena | 74 |
Maintenant, lançons quelques requêtes et voyons les résultats :
- Somme de toutes les notes :
SUM()
SELECT SUM(score) AS total_score
FROM students_scores;
Résultat :
| total_score |
|---|
| 251 |
Comme tu vois, les valeurs NULL manquantes n’ont juste pas été prises en compte dans la somme. Pour Alisa (85), Charlie (92) et Elena (74), la somme fait 251. Bob et Dana sont restés sur le carreau.
- Moyenne des notes :
AVG()
SELECT AVG(score) AS average_score
FROM students_scores;
Résultat :
| average_score |
|---|
| 83.67 |
Là encore, les NULL sont ignorés, et la moyenne est calculée seulement pour ceux qui ont une note : (85 + 92 + 74) / 3 = 83.67.
- Note minimale et maximale :
MIN()etMAX()
SELECT
MIN(score) AS min_score,
MAX(score) AS max_score
FROM students_scores;
Résultat :
| min_score | max_score |
|---|---|
| 74 | 92 |
Ici aussi, c’est simple : les valeurs NULL sont encore ignorées, donc la note minimale est 74 et la maximale — 92.
- Comptage des lignes :
COUNT(*)vsCOUNT(colonne)
SELECT
COUNT(*) AS total_rows,
COUNT(score) AS non_null_scores
FROM students_scores;
Résultat :
| total_rows | non_null_scores |
|---|---|
| 5 | 3 |
COUNT(*)a compté toutes les lignes, même celles oùscorevautNULL.COUNT(score)a compté seulement les lignes où la colonnescorea une valeur.
Cas pratiques
Voici quelques exemples concrets.
Exemple 1 : Compter les employés avec ou sans salaire renseigné
Imaginons qu’on a une table employees avec les salaires.
| id | name | salary |
|---|---|---|
| 1 | Alex Lin | 50000 |
| 2 | Maria Chi | NULL |
| 3 | Anna Song | 60000 |
| 4 | Otto Art | NULL |
| 5 | Liam Park | 55000 |
On veut savoir combien d’employés ont renseigné leur salaire, et combien ne l’ont pas fait.
SELECT
COUNT(*) AS total_employees,
COUNT(salary) AS employees_with_salary,
COUNT(*) - COUNT(salary) AS employees_without_salary
FROM employees;
Ici :
COUNT(*)va donner le nombre total d’employés.COUNT(salary)va compter ceux qui ont renseigné leur salaire.- Pour avoir le nombre d’employés sans salaire, on fait juste la différence entre les deux.
Résultat
| total_employees | employees_with_salary | employees_without_salary |
|---|---|---|
| 5 | 3 | 2 |
Exemple 2 : Calculer le prix moyen des produits avec des données manquantes
Tu es le boss d’une boutique magique, et dans la table products il y a une colonne price, mais certains produits n’ont pas encore de prix.
| id | name | price |
|---|---|---|
| 1 | Magic Wand | 150 |
| 2 | Enchanted Cloak | NULL |
| 3 | Potion Bottle | 75 |
| 4 | Spell Book | 200 |
| 5 | Crystal Ball | NULL |
Tu veux connaître le prix moyen seulement pour les produits qui ont un prix renseigné.
SELECT AVG(price) AS average_price
FROM products;
Résultat :
| average_price |
|---|
| 141.6667 |
Si tu veux mettre un prix par défaut pour les produits sans prix (genre 0), tu peux utiliser la fonction COALESCE() qu’on verra dans la prochaine leçon.
Exemple 3 : Trouver l’âge minimal et maximal des étudiants
Dans la table students on a l’âge des étudiants, mais pour certains l’âge est inconnu (NULL).
| id | name | age |
|---|---|---|
| 1 | Alex Lin | 20 |
| 2 | Maria Chi | NULL |
| 3 | Anna Song | 19 |
| 4 | Otto Art | 22 |
| 5 | Liam Park | NULL |
On veut savoir qui est le plus jeune et le plus âgé.
SELECT
MIN(age) AS youngest_student,
MAX(age) AS eldest_student
FROM students;
Résultat :
| youngest_student | eldest_student |
|---|---|
| 19 | 22 |
Cette requête va te donner l’âge minimal et maximal seulement pour les étudiants dont l’âge est renseigné. NULL sera encore zappé.
Particularités et pièges à éviter
Quand tu bosses avec NULL dans les agrégats, retiens bien ces points :
- Dans la somme
SUM()et la moyenneAVG(), lesNULLne sont pas pris en compte. Ça peut t’éviter d’ajouter des “valeurs vides” dans tes calculs. - Si tu veux compter les lignes avec
NULLdans la colonne, utiliseCOUNT(*). - Avec
MIN()ouMAX(),NULLn’influence pas le résultat. Mais si toute la colonne est remplie uniquement deNULL, le résultat sera aussiNULL.
Conseils pour bosser avec NULL
- Adapte-toi à la situation. C’est important de comprendre si tu dois prendre en compte les
NULLdans ta requête. Parfois, comme avecAVG(), les ignorer c’est ce qu’il faut. Mais parfois, comme pour compter le total, il faut aussi compter les lignes avecNULL. - Utilise
COALESCE()si besoin. Si tu veux remplacer lesNULLpar une valeur par défaut dans tes calculs, la fonctionCOALESCE()va devenir ton alliée (mais ça, c’est pour la prochaine leçon). - Ne confonds pas
COUNT(*)etCOUNT(colonne). C’est l’erreur classique des débutants. Le premier compte toutes les lignes, le second — seulement celles avec une valeur non nulle.
Maintenant tu sais comment ce discret NULL peut influencer les agrégats. Cette connaissance va t’éviter des surprises et te permettre d’utiliser NULL à ton avantage. Dans la prochaine leçon, on va découvrir l’outil puissant COALESCE() pour gérer les NULL encore plus efficacement.
GO TO FULL VERSION