Retour à la liste des articles Articles
6 minutes de lecture

La clause HAVING en SQL expliquée

Qu'est-ce que la clause HAVING de SQL ? Pourquoi en avez-vous besoin, et où l'utiliser ? Nous allons expliquer la clause HAVING en détail.

HAVING est une clause très courante dans les requêtes SQL. Tout comme WHERE, elle permet de filtrer les données ; cependant, HAVING fonctionne de manière différente. Si vous connaissez la clause GROUP BY et que vous n'avez entendu parler que de HAVING - ou si vous ne connaissez pas du tout HAVING - cet article est ce qu'il vous faut. Poursuivez votre lecture et approfondissez vos connaissances sur les HAVING en SQL !

Qu'est-ce que la clause HAVING en SQL ?

En SQL, la clause HAVING :

  • Filtre les données en fonction de critères définis.
  • Est couramment utilisée pour créer des rapports.
  • Est uniquement utilisée dans SELECT.
  • Fonctionne avec GROUP BY.

Si vous connaissez la clause GROUP BY, vous savez qu'elle est utilisée pour agréger des valeurs : elle place les enregistrements dans des groupes afin de calculer des valeurs d'agrégation (statistiques) pour ceux-ci. HAVING filtre les enregistrements en fonction de ces valeurs d'agrégation. Nous allons en parler en détail ici, mais vous trouverez plus de détails dans notre cours interactif SQL pour les débutants.

Si vous avez besoin de rafraîchir vos connaissances sur GROUP BY, je vous recommande les articles Getting the Hang of the GROUP BY Clause de Marian Dziubak et Grouping Data in SQL Server de Belma Mesihovic.

Syntaxe du HAVING

Avant de commencer par un exemple, examinons la syntaxe de la clause HAVING. La clause HAVING est toujours placée après les clauses WHERE et GROUP BY mais avant la clause ORDER BY. Regardez :

SELECT column_list 
FROM table_name
WHERE where_conditions
GROUP BY column_list
HAVING having_conditions
ORDER BY order_expression

La clause HAVING spécifie la ou les conditions d'un groupe ou d'une agrégation.

Le tableau employee tableau ci-dessous nous aide à analyser la clause HAVING. Il contient les ID des employés (la colonne emp_id ), le site department où travaille cet employé et le site salary de l'employé.

employee_iddepartmentsalary
1HR23000
2HR28000
3Finance35000
4Marketing15000
5Marketing25000
6Finance56000
7Finance41000

Pour calculer la somme des salaires de chaque département, vous écrivez cette requête :

SELECT department, SUM(salary)
FROM employee
GROUP BY department;

Voici le résultat :

departmentsalary
HR51000
Marketing40000
Finance132000

Maintenant, supposons que vous ayez besoin d'afficher les départements où la somme des salaires est égale ou supérieure à 50 000 $. Dans ce cas, vous devez utiliser une clause HAVING :

SELECT department, SUM(salary)
FROM employee
GROUP BY department
HAVING SUM(salary) >= 50000;

Et le résultat est :

departmentsalary
HR51000
Finance132000

Comme vous le voyez, le jeu de résultats ne contient que la somme des salaires des départements RH et Finance. Cela s'explique par le fait que la somme des salaires du département Marketing est inférieure à 50 000 $.

Cette requête regroupe d'abord les enregistrements en fonction des départements et calcule les valeurs agrégées - dans ce cas, la somme de tous les salaires. À l'étape suivante, la condition dans HAVING est vérifiée : nous comparons la valeur renvoyée par SUM(salary) pour un département donné à 50 000 $. Si cette valeur est égale ou supérieure à 50 000 $, l'enregistrement est renvoyé. Dans notre exemple, les salaires additionnés pour les départements RH (51 000 $) et Finance (132 000 $) sont affichés.

Filtrage des lignes à l'aide de WHERE et HAVING

Ensuite, voyons comment filtrer les lignes au niveau de l'enregistrement et au niveau du groupe dans la même requête. Tout d'abord, regardez les données dans le tableau du rapport sale:

salesman_idsale_monthtotal_value
1January34000
1February14000
1March22000
1April2000
2January20000
2February0
2March17000
2April0
3March1000
3April35000

La requête ci-dessous sélectionne la somme de toutes les ventes pour chaque vendeur dont la valeur moyenne des ventes est supérieure à 20 000 dollars. (Remarque : le vendeur avec ID=3 n'est pas inclus, car il n'a commencé à travailler qu'en mars).

SELECT salesman_id, SUM(total_value)  
FROM sale 
WHERE salesman_id != 3
GROUP BY salesman_id 
HAVING SUM(total_value) > 40000;

Voici le résultat :

salesman_idsum
172000

Cette requête filtre d'abord les enregistrements, en utilisant la clause WHERE pour sélectionner les enregistrements dont l'ID du vendeur est différent de 3 (WHERE salesman_id != 3). Ensuite, elle calcule la somme des ventes totales pour les vendeurs ayant les ID 1 et 2. Pour ce faire, elle regroupe individuellement les enregistrements des deux représentants (GROUP BY salesman_id). Enfin, la requête filtre les enregistrements en utilisant HAVING pour vérifier si la valeur agrégée (somme des ventes totales) est supérieure à 40 000 $ (HAVING SUM(total_value) > 40000)).

Filtrage des enregistrements sur plusieurs valeurs à l'aide de la clause HAVING

La clause HAVING vous permet également de filtrer des enregistrements en utilisant plus d'une valeur agrégée (c'est-à-dire des valeurs provenant de différentes fonctions d'agrégation). Regardez la requête suivante :

SELECT salesman_id, SUM(total_value) 
FROM sale 
WHERE salesman_id != 3
GROUP BY salesman_id 
HAVING SUM(total_value) > 36000 AND AVG(total_value) > 15000;

Le résultat :

salesman_idsum
172000

Cette requête renvoie les ID des commerciaux qui 1) ont un chiffre d'affaires total supérieur à 36 000 $, et 2) réalisent en moyenne plus de 15 000 $ de chiffre d'affaires chaque mois. Seul le commercial avec ID=1 remplit les deux conditions. Remarquez que nous n'avons pas sélectionné la moyenne des ventes totales pour chaque vendeur, mais seulement la somme de toutes leurs ventes ; la moyenne figure uniquement dans la condition HAVING.

La différence entre HAVING et WHERE

L'exemple de la section précédente montrait comment filtrer des enregistrements à l'aide des conditions WHERE et HAVING. Nous allons maintenant examiner la différence entre ces deux clauses.

La différence fondamentale est que la clause WHERE porte sur des enregistrements individuels et que la clause HAVING porte sur des enregistrements groupés (après traitement du GROUP BY). La clause HAVING est utilisée uniquement dans les instructions SELECT, mais la clause WHERE peut être utilisée dans d'autres instructions, comme DELETE ou UPDATE.

HAVING et WHERE filtrent les données à des moments différents. WHERE est traité avant GROUP BY. Cela signifie que les enregistrements sont d'abord sélectionnés, puis filtrés avec WHERE. Il s'agit d'un filtrage au niveau des enregistrements. Après cela, les enregistrements du résultat sont regroupés et la valeur agrégée est calculée.

HAVING filtre les enregistrements au niveau du groupe - après WHERE et GROUP BY. HAVING vérifie si la valeur agrégée d'un groupe répond à sa ou ses conditions. Vous devez utiliser une fonction d'agrégation pour filtrer les enregistrements uniquement dans HAVING ; WHERE ne peut pas inclure de fonction d'agrégation.

Pour en savoir plus sur la différence entre WHERE et HAVING, consultez la rubrique HAVING vs. WHERE en SQL : Ce que vous devez savoir par Ignacio L. Bisso.

HAVING : une clause très utile

La clause HAVING est très utile dans les requêtes SQL. Elle filtre les données après le regroupement des lignes et l'agrégation des valeurs, ce qui est souvent le cas dans les rapports.

J'espère que cet article vous a aidé à comprendre la clause HAVING. Peut-être vous a-t-il même incité à étendre vos connaissances en SQL. Si vous souhaitez en apprendre davantage sur SQL, essayez notre cours interactif SQL pour les débutants cours interactif sur la LearnSQL.fr plateforme.