CodeGym /Cours /SQL SELF /Filtrer les données agrégées avec HAVING

Filtrer les données agrégées avec HAVING

SQL SELF
Niveau 8 , Leçon 1
Disponible

Un truc qu’on n’a pas encore vu, c’est comment filtrer les groupes après avoir appliqué des agrégats ? Parfois, on ne veut pas tous les départements — juste ceux où il y a plus de cent étudiants. Ou alors on veut voir uniquement les services où le salaire moyen dépasse 50 000. Aujourd’hui, on va découvrir comment filtrer les données agrégées avec HAVING.

Mais pourquoi on a besoin de HAVING alors qu’on a déjà WHERE ? On pourrait juste mettre WHERE après GROUP BY :)

C’est pas si simple ! Déjà, l’ordre des opérateurs en SQL est fixé et WHERE s’exécute avant GROUP BY.

Et si on essayait de le mettre après GROUP BY ?

Non plus ! Très souvent, il faut filtrer les lignes du tableau avant de grouper. Ensuite, on fait le groupement sur les données filtrées. Et après, on veut encore virer des groupes inutiles après l’agrégation.

Alors, on pourrait juste copier l’opérateur WHERE, l’appeler HAVING et le coller après GROUP BY ?

Ouais, c’est exactement ça ! :)

Différence entre HAVING et WHERE

WHERE filtre les lignes avant le groupement.

Imagine que tu sélectionnes des gâteaux selon leur goût : tu gardes les fraise et chocolat, les autres tu les mets de côté. Ça, c’est le taf de WHERE.

HAVING filtre après que les données ont été groupées et que les fonctions d’agrégat ont fait leur magie.

Par exemple, t’as déjà groupé les gâteaux par table, compté combien il y en a, et maintenant tu veux garder que les tables où il y a plus de trois gâteaux.

Donc, HAVING sert à filtrer les données au niveau des groupes.

Syntaxe de HAVING

La syntaxe est presque la même que pour WHERE, mais ça marche un peu différemment :

SELECT colonnes, fonctions_aggrégées
FROM table
GROUP BY colonnes
HAVING condition;

Étapes d’exécution :

  1. D’abord, les lignes sont filtrées avec WHERE.
  2. Ensuite, les données sont groupées avec GROUP BY.
  3. Les fonctions d’agrégat sont appliquées aux résultats du groupement.
  4. Enfin, le résultat obtenu est filtré avec HAVING.

Exemples d’utilisation de HAVING

Exemple 1 : Filtrer les facultés avec beaucoup d’étudiants

Tu veux savoir quelles facultés à l’université ont plus de 100 étudiants. Imaginons qu’on a une table students :

id name faculty
1 Alice Engineering
2 Bob Engineering
3 Charlie Arts
4 Daisy Business
5 ... ...

Requête :

SELECT faculty, COUNT(*) AS student_count
FROM students
GROUP BY faculty
HAVING COUNT(*) > 100;

Ce qui se passe ici :

  • D’abord, on groupe les étudiants par colonne faculty avec GROUP BY.
  • Puis la fonction d’agrégat COUNT(*) compte le nombre d’étudiants dans chaque faculté.
  • Enfin, HAVING vire toutes les facultés où il y a 100 étudiants ou moins.

Résultat :

faculty student_count
Engineering 150
Arts 120

Exemple 2 : Départements avec un salaire moyen élevé

Tu veux trouver seulement les départements où le salaire moyen des employés dépasse 50 000. Imaginons qu’on a une table employees :

id name department salary
1 Alice IT 60000
2 Bob HR 45000
3 Charlie IT 70000
4 Daisy HR 52000
5 ... ... ...

Requête :

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;

Résultat :

department avg_salary
IT 65000

À noter : HAVING bosse avec les résultats calculés après GROUP BY.

Ordre d’exécution de WHERE, GROUP BY et HAVING

Le filtrage avec WHERE et HAVING se fait à des étapes différentes. Pour mieux piger la différence, voilà le process étape par étape :

  1. WHERE : filtrage des lignes.

    À ce stade, toutes les lignes du tableau sont traitées. Si une ligne ne passe pas la condition WHERE, elle ne va même pas plus loin.

  2. GROUP BY : groupement des lignes.

    Après le filtrage, les lignes sont regroupées selon les colonnes indiquées dans GROUP BY.

  3. Fonctions d’agrégat :

    Les fonctions d’agrégat comme COUNT(), AVG(), SUM() etc. sont appliquées aux groupes.

  4. HAVING : filtrage des groupes.

    Là, on ne traite que les résultats des agrégats. Les conditions HAVING s’appliquent uniquement aux groupes.

Particularités de HAVING

Particularité 1 : Travailler avec les agrégats

La grosse différence entre HAVING et WHERE, c’est la gestion des fonctions d’agrégat. Par exemple :

SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;

Dans cette requête, tu peux pas utiliser AVG(salary) dans WHERE, parce que WHERE traite les lignes avant le groupement. Une requête comme :

SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;

va te donner une erreur : aggregate functions are not allowed in WHERE.

Particularité 2 : Filtrer sans groupement

Tu peux utiliser HAVING même sans GROUP BY explicite. Dans ce cas, la requête est vue comme s’il y avait un seul groupe — toutes les lignes :

SELECT AVG(salary) AS avg_salary
FROM employees
HAVING AVG(salary) > 50000;

Exemple pratique

Imaginons qu’on a un magasin et une table des ventes sales :

id product_id sales_amount
1 101 200.00
2 102 300.00
3 101 400.00
4 103 150.00

Requête : trouver les produits avec un total des ventes supérieur à 500.

SELECT product_id, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING SUM(sales_amount) > 500;

Résultat :

product_id total_sales
101 600.00

Erreurs classiques

Utiliser des agrégats dans WHERE :

Par exemple :

SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;

Erreur : tu peux pas utiliser des fonctions d’agrégat dans WHERE.

Erreurs avec NULL :

Si les données contiennent des NULL, le filtrage peut donner des résultats bizarres. Par exemple :

SELECT department, SUM(salary)
FROM employees
GROUP BY department
HAVING SUM(salary) > 0;

Si la colonne salary contient seulement des NULL, le résultat peut être zéro ou vide.

Bravo ! À ce stade, tu sais déjà filtrer les données agrégées comme un chef ! N’oublie pas, HAVING c’est ta clé pour l’analyse au niveau des groupes, là où un simple WHERE ne suffit plus.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION