Accéder au contenu principal

La différence entre WHERE et HAVING en SQL

Découvrez comment WHERE filtre les données au niveau des lignes dans les requêtes SQL, tandis que HAVING filtre les données groupées après agrégation, et maîtrisez leurs utilisations distinctes dans les requêtes SQL.
Actualisé 14 févr. 2025  · 8 min lire

WHERE et HAVING sont deux clauses essentielles de SQL. Que vous écriviez des requêtes très avancées ou très simples, vous aurez besoin d'utiliser les deux. Vous pouvez considérer WHERE et HAVING comme des frères et sœurs. Ils remplissent tous deux une fonction similaire (filtrage) et apparaissent souvent ensemble. Mais, tout comme les frères et sœurs, ils ont des caractéristiques distinctes et des rôles uniques. 

Si vous êtes en train de trier WHERE et HAVING, je vous suggère de vous inscrire à notre cursus de compétences SQL Fundamentals, qui constitue un excellent point de départ. Vous y apprendrez les différentes clauses SQL, l 'ordre d'exécution SQL, l'optimisation des requêtes SQL et bien d'autres choses essentielles.  

La réponse courte : Où vs. AVOIR 

La réponse courte et la source de confusion pour beaucoup de gens est que WHERE travaille sur des données au niveau des lignes, tandis que HAVING travaille sur des données groupées. Voici une ligne directrice :

  • WHERE filtre les lignes avant tout regroupement ou agrégation. Elle s'applique à des lignes individuelles et ne peut pas être utilisée avec des fonctions d'agrégation.

  • HAVING filtre les groupes une fois que le regroupement et l'agrégation ont été effectués. Il s'applique aux résultats des fonctions agrégées et est utilisé en combinaison avec GROUP BY.

Un exemple rapide pour montrer la différence 

Prenons un exemple rapide. Si vous souhaitez suivre votre propre flux de travail, vous pouvez télécharger l'ensemble de données sur les locations immobilières à partir de ce dépôt GitHub.

Supposons maintenant que nous ayons besoin de retourner toutes les propriétés de notre ensemble de données dont le prix de location est inférieur à 500 $. Le niveau de détail de chaque ligne de l'ensemble de données (un bien par ligne) correspond au niveau de détail de la condition d'interrogation. Par conséquent, nous utilisons WHERE dans la requête suivante :

SELECT *
FROM rentals
WHERE rental_price < 500

Le résultat serait le suivant. Vous remarquerez que 118 lignes sont renvoyées.

Filtrage simple des lignes avec SQL WHERE

Filtrage simple des lignes avec WHERE. Image par l'auteur.

Supposons maintenant que nous ne souhaitions pas avoir un tableau des biens immobiliers, mais des villes dont le prix de location moyen est inférieur à 2 700 $. Au lieu que chaque ligne corresponde à un bien immobilier, nous regrouperons les lignes et agrégerons le prix de location pour obtenir un prix de location moyen pour chaque ville. Nous utiliserons donc HAVING, comme dans cette requête :

SELECT city, AVG(rental_price) AS average_rent
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;

Et le résultat serait. Remarquez qu'il n'y a qu'un seul résultat. 

Filtrage simple de groupes avec SQL HAVING

Filtrage de groupe simple avec HAVING. Image par l'auteur.

WHERE, HAVING et ordre d'exécution SQL

Nous constatons que WHERE fonctionne avec un filtrage au niveau de la ligne, tandis que HAVING fonctionne avec un filtrage au niveau de l'agrégat. La compréhension de cette différence ouvre également la voie à l'apprentissage de l' ordre d'exécution des clauses de SQL.

WHERE est évaluée avant GROUP BY et juste après FROM (et JOIN le cas échéant) ; elle ne peut traiter aucun regroupement ou agrégation. WHERE entre en jeu avant toute agrégation. C'est pourquoi il n'opère que sur des données au niveau de la ligne. 

Par ailleurs, HAVING vient après l'exécution de la clause GROUP BY. Cela signifie qu'il intervient après avoir transformé le tableau et l'avoir regroupé à un niveau différent du niveau de granularité du tableau source. HAVING opère sur la nouvelle version transformée du tableau. 

Comment utiliser la clause WHERE en SQL

Prenons un peu de recul et examinons chaque clause séparément. Nous pouvons commencer par la clause WHERE.

Syntaxe et instructions WHERE

WHERE peut être utilisé dans trois instructions SQL différentes : SELECT, UPDATE, et DELETE.

WHERE dans les instructions SELECT

Dans les instructions SELECT, qui sont les instructions utilisées pour extraire des données de la base de données, WHERE joue un rôle direct dans le filtrage au niveau des lignes et a sa place bien connue juste après la clause FROM, comme nous pouvons le voir dans la requête suivante :

SELECT column1, column2… etc.
FROM table_name
WHERE condition;

WHERE utilisé avec SELECT est l'endroit où la clause WHERE est le plus souvent confondue avec HAVING

WHERE dans les instructions UPDATE

En outre, WHERE joue un rôle important dans les instructions UPDATE pour déterminer la ligne où la mise à jour des données doit avoir lieu, comme nous pouvons le voir avec la syntaxe suivante :

UPDATE table_name
SET column_name1 = value1, column_name2 = value2… etc.
WHERE condition;

WHERE dans les instructions DELETE

WHERE est également un complément utile aux instructions DELETE pour préciser les enregistrements (lignes) qui doivent être supprimés, comme nous pouvons le voir ici :

DELETE FROM table_name
WHERE condition;

Comment rédiger les conditions WHERE

WHERE sont écrites sous la forme d'une simple expression logique. Il se compose de trois parties : la variable/l'opérande, la condition et la valeur/le résultat. Examinons les options des conditions WHERE, qui comprennent à la fois des opérateurs logiques et des opérateurs de comparaison.  

Panneau de l'opérateur Description Type de données de l'opérande
= Egale à (à la date) Numérique, Texte, Date/horaire, Booléen
< Moins de (avant la date) Numérique, Date/horaire
> Supérieur à (après la date) Numérique, Date/horaire
<= Inférieur ou égal à (à la date ou avant) Numérique, Date/horaire
>= Supérieur ou égal à (à la date ou après la date) Numérique, Date/horaire
<> (!=) Pas égal à (pas à la date) Numérique, Texte, Date/horaire, Booléen
IN Égal à plus d'une valeur (à plusieurs dates) Numérique, Texte, Date/horaire, Booléen (mais cela n'a pas de sens !)
LIKE Correspond à un modèle de texte (à l'aide de caractères génériques) Texte
BETWEEN Existe dans une gamme Numérique, Date/horaire
ET Combine plusieurs conditions, toutes doivent être vraies Logique (booléen)
OU Combine plusieurs conditions, dont l'une au moins doit être vraie Logique (booléen)
NOT Négation d'une condition Logique (booléen)
EST NULL Vérifie les valeurs nulles Tous les types de données
IS NOT NULL Vérifie les valeurs non nulles Tous les types de données

Voici un exemple où nous utilisons NOT avec l'opérateur de comparaison IN:

SELECT *
FROM rentals
WHERE city NOT IN ('Cairo', 'Giza');

La déclaration renverra tous les biens qui ne se trouvent ni dans la ville du Caire ni dans celle de Gizeh.

Utilisation de NOT avec WHERE

Propriétés en dehors du Caire et de Gizeh. Image par l'auteur.

Cas d'utilisation

Sachant que WHERE fonctionne avec les instructions SELECT, UPDATE et DELETE, nous pouvons prévoir qu'il peut être utilisé pour trois cas d'utilisation : le filtrage au niveau des lignes, l'extraction de données et la manipulation de données.

Filtrage au niveau des lignes

Nous pouvons filtrer les tableaux en fonction d'une ou plusieurs conditions. La requête suivante filtre les lignes pour n'inclure que les propriétés des villas.

SELECT *
FROM rentals
WHERE type = ‘villa’;

Utilisation de NOT avec WHERE

Sélection de propriétés de villas. Image par l'auteur.

Recherche de données

WHERE peut être utilisé pour récupérer un point de données spécifique que nous recherchons. Cette méthode est similaire au filtrage au niveau des lignes, mais elle est plus spécifique. En supposant que nous ayons besoin de connaître l'ID du bien qui était disponible le 1er janvier 2022 au Caire, nous pouvons utiliser la requête suivante :

SELECT property_id
FROM rentals
WHERE available_date = '2022-01-01'
AND city = 'Cairo';

Filtrage au niveau des lignes avec WHERE

Récupération d'un point de données. Image par l'auteur.

Manipulation des données

Enfin, WHERE est une aide précieuse pour modifier des valeurs et supprimer des enregistrements spécifiques dans votre base de données. Par exemple, si nous découvrons que le bien 171 n'accepte pas les animaux, nous pouvons modifier la colonne pet_friendly en utilisant WHERE dans une déclaration UPDATE comme suit :

UPDATE rentals
SET pet_friendly = false
WHERE property_id = 171;

Comment utiliser la clause HAVING en SQL

Il est maintenant temps d'aborder la clause HAVING avec le même niveau de détail. 

Syntaxe et déclarations HAVING

Tout d'abord, il faut savoir que la clause HAVING ne peut être utilisée que dans les déclarations SELECT. Par conséquent, la seule syntaxe possible est la suivante :

SELECT grouped_column, aggregate_function(aggregated_column)… etc.
FROM table_name
GROUP BY grouped_column
HAVING condition

Notez que vous pouvez ajouter plus d'une colonne groupée et plus d'une colonne agrégée. Nous en verrons des exemples ci-dessous.

Comment rédiger des conditions de type "HAVING" ?

Comme WHERE, les conditions HAVING sont écrites sous forme d'expressions logiques, mais avec un élément supplémentaire, la fonction d'agrégation. Ainsi, une condition HAVING se compose de 1) une fonction agrégée, 2) une variable/opérande, 3) un opérateur de comparaison et 4) une valeur/résultat.

Fonctions d'agrégation avec HAVING

SQL dispose principalement de cinq fonctions d'agrégation, plus une sixième qui est un cas particulier. Ces fonctions sont les suivantes

Fonction agrégée Type de données approprié
SUM() Numérique
AVG() Numérique
MIN() Numérique, Texte, Date/horaire
MAX() Numérique, Texte, Date/horaire
COUNT() Numérique, Texte, Date/horaire, Booléen

Prenons un exemple. Ici, nous utilisons la fonction COUNT() avec GROUP BY pour créer un tableau de fréquences, et nous utilisons la condition HAVING comme filtre. Plus précisément, nous devons connaître les villes qui sont mentionnées 150 fois ou moins, ce qui, dans ce contexte, correspond au nombre d'enregistrements. Nous pouvons utiliser cette requête :

SELECT city, COUNT(*) AS properties_count
FROM rentals
GROUP BY city
HAVING COUNT(*) <= 150;

Utilisation de MAX() avec HAVING

Utilisation de COUNT() avec HAVING. Image par l'auteur.

Comparaison et opérateurs logiques

HAVING accepte tous les opérateurs logiques et de comparaison acceptés par WHERE. La seule différence est que le type de données approprié avec HAVING dépend avant tout de la fonction d'agrégation, comme nous pouvons le voir dans le tableau ci-dessus.

Exemples d'utilisation

Contrairement à WHERE, HAVING ne peut pas être utilisé dans les déclarations UPDATE et DELETE; HAVING n'est utilisé que pour la recherche de données. En gros, cela se traduit par deux scénarios :

Filtrage au niveau du groupe

C'est l'usage courant et normal de HAVING. Vous pouvez par exemple ne retenir que les villes où le prix moyen des loyers est inférieur à 2 700 $.

SELECT city, AVG(rental_price) AS avg_price
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;

Filtrage à une rangée

Il s'agit d'un cas peu courant, mais HAVING peut être utilisé pour renvoyer une agrégation d'une seule ligne, comme une métrique ou un indicateur de performance clé, uniquement si elle remplit une certaine condition. Ceci peut être réalisé par l'utilisation de HAVING sans GROUP BY. Dans l'exemple suivant, nous ne renvoyons le prix de location moyen que s'il est inférieur à 2 800 $. Si la mesure remplit la condition, nous obtiendrons un résultat sur une seule ligne. Dans le cas contraire, nous aurions un tableau vide.

SELECT AVG(rental_price) as avg_price
FROM rentals
HAVING AVG(rental_price) > 2800;

Combiner WHERE et HAVING

WHERE et HAVING peuvent être combinés pour filtrer les tableaux avant et après l'agrégation. Dans l'exemple suivant, nous renvoyons le nombre de biens dans chaque ville, en ne comptant que les biens qui acceptent les animaux et en filtrant les villes qui ont plus de 80 biens.

SELECT city, COUNT(*) AS number_properties
FROM rentals
WHERE pet_friendly = true
GROUP BY city
HAVING COUNT(*) > 80;

Combiner WHERE avec HAVING

Combinaison de base de WHERE et HAVING. Image par l'auteur.

La différence entre WHERE et HAVING dans les performances

Nous savons que la clause WHERE est appliquée avant le regroupement ou l'agrégation. Mais nous devons également savoir que, pour cette raison, parce qu'il réduit le nombre de lignes traitées au début de la requête, WHERE est plus efficace pour filtrer des lignes individuelles. 

Nous savons, par ailleurs, que la clause HAVING est appliquée après l'agrégation et filtre l'ensemble des résultats sur la base des données groupées. C'est pourquoi, parce qu'il traite les données après que toutes les lignes ont été regroupées, il est généralement moins efficace que WHERE, bien qu'il soit toujours nécessaire pour les conditions impliquant des fonctions agrégées.

Examinons cette requête :

SELECT city, COUNT(*)
FROM rentals
GROUP BY city
HAVING rental_price < 2700;

Cette requête est inefficace car la condition rental_price ne dépend d'aucune agrégation - elle filtre des lignes individuelles. Cette requête regroupe d'abord toutes les locations par ville, les compte, puis filtre le résultat, ce qui est inefficace car cela traite des lignes inutiles. Pour cette raison, cette requête aurait été plus rapide :

SELECT city, COUNT(*)
FROM rentals
WHERE rental_price < 2700
GROUP BY city;

Conseils d'optimisation WHERE et HAVING

Sur la base de ce qui précède, nous pouvons voir certaines des bonnes pratiques qui peuvent optimiser notre utilisation des clauses WHERE et HAVING. Ceci est important si vous avez de grands ensembles de données.

  1. Soyez très sélectif : Filtrez en fonction des valeurs que vous souhaitez filtrer et pas plus. Cela permettra de réduire le nombre de lignes dans la vue et donc d'améliorer l'efficacité de la requête.

  2. Soyez simple : Supprimez les conditions, les agrégations et les caractères d'imprimerie inutiles. Tous ces avantages ont un prix calculatoire.

  3. Filtre précoce : Si vous effectuez une agrégation au niveau du groupe, préfiltrez les lignes avec WHERE pour accélérer le processus de regroupement. Ce faisant, vous réduisez le nombre de lignes à traiter dans le regroupement.

Tableau de comparaison

Résumons nos réflexions dans un tableau pratique :

Comparaison WHERE AVOIR
Objectif principal Filtrage au niveau des lignes Filtrage au niveau du groupe
Syntaxe de base SELECT colonne1, colonne2... FROM nom_table WHERE condition ; SELECT colonne_groupée, fonction_agrégée(colonne_agrégée)... FROM nom_table GROUP BY colonne_groupée HAVING condition ;
Ordre d'évaluation Avant GROUP BY Après GROUP BY
Déclarations compatibles SÉLECTIONNER, METTRE À JOUR, SUPPRIMER  SELECTIONNER
Conditions Impossible d'inclure des fonctions agrégées Doit inclure des fonctions agrégées
Cas d'utilisation Filtrage au niveau des lignes Extraction des données Manipulation des données Filtrage au niveau du groupe Filtrage sur une seule ligne
Sous-requêtes Peut fonctionner avec des sous-requêtes Doit être écrit sous forme d'ETC

Conclusion

Tout au long de l'article, nous avons exploré la principale différence entre WHERE et HAVING en SQL, à savoir que la clause WHERE filtre les lignes avant l'agrégation, tandis que la clause HAVING filtre les données groupées après l'agrégation. Nous avons également exploré certaines différences moins connues, comme le fait que WHERE peut fonctionner avec les déclarations SELECT, UPDATE et DELETE, mais que HAVING ne fonctionne qu'avec SELECT. Nous avons également parlé de la performance.

L'aide-mémoire de DataCamp sur les bases de SQL fournit une synthèse intéressante des clauses WHERE et HAVING, ainsi que des conseils sur la manière d'effectuer des filtrages en SQL. Par ailleurs, si vous débutez dans le domaine du langage SQL, vous pouvez consulter le cursus de compétences SQL Fundamentals et le cursus de carrière Associate Data Analyst in SQL


Islam Salahuddin's photo
Author
Islam Salahuddin

Islam est consultant en données à l'Institut KPI. Issu d'une formation en journalisme, Islam s'intéresse à divers domaines, dont l'écriture, la philosophie, les médias, la technologie et la culture.

Questions fréquemment posées

Quelle est la différence entre OÙ et AVOIR ?

WHERE effectue un filtrage au niveau de la ligne, tandis que HAVING effectue un filtrage au niveau du groupe.

Puis-je combiner WHERE et HAVING dans une même requête ?

Oui, et il est fortement recommandé d'utiliser WHERE si vous avez l'intention d'utiliser HAVING.

Est-ce que WHERE peut fonctionner avec des fonctions agrégées comme HAVING ?

Non, seul HAVING peut utiliser les fonctions agrégées.

Est-ce que WHERE et HAVING fonctionnent avec les mêmes opérateurs logiques et de comparaison ?

Oui, les deux fonctionnent avec les mêmes opérateurs car les conditions WHERE et HAVING sont écrites sous forme d'expressions logiques.

Puis-je utiliser HAVING sans GROUP BY ?

HAVING est généralement utilisé après le regroupement avec GROUP BY. La seule exception à cette règle est le filtrage des vues à valeur unique (comme le calcul d'une métrique).

Sujets

Apprenez SQL avec DataCamp

Cours

Manipulation de données en SQL

4 h
318.1K
Débloquez tout le potentiel de vos données grâce à des requêtes SQL avancées et préparez des jeux de données robustes avec PostgreSQL pour la data science.
Afficher les détailsRight Arrow
Commencer le cours
Voir plusRight Arrow
Contenus associés

blog

Architecture de l'entrepôt de données : Tendances, outils et techniques

Apprenez l'essentiel de l'architecture d'un entrepôt de données, des composants clés aux meilleures pratiques, pour construire un système de données évolutif et efficace !
Kurtis Pykes 's photo

Kurtis Pykes

15 min

Tutoriel

Normalisation vs. Standardisation: comment faire la différence

Découvrez les principales différences, les applications et la mise en œuvre de la normalisation et de la standardisation dans le prétraitement des données pour l’apprentissage automatique.
Samuel Shaibu's photo

Samuel Shaibu

Tutoriel

Tutoriel Python sur les structures de données

Initiez-vous aux structures de données de Python : apprenez-en plus sur les types de données et les structures de données primitives et non primitives, telles que les chaînes de caractères, les listes, les piles, etc.
Sejal Jaiswal's photo

Sejal Jaiswal

Tutoriel

Python Switch Case Statement : Guide du débutant

Découvrez le match-case de Python : un guide sur sa syntaxe, ses applications en data science, ML, et une analyse comparative avec le switch-case traditionnel.
Matt Crabtree's photo

Matt Crabtree

Tutoriel

Fonctions lambda Python : Guide pour débutants

Découvrez les fonctions lambda Python, leur utilité et quand les utiliser. Comprend des exemples pratiques et des bonnes pratiques pour une mise en œuvre efficace.
Mark Pedigo's photo

Mark Pedigo

Tutoriel

Instructions IF, ELIF et ELSE en Python

Dans ce tutoriel, vous apprendrez exclusivement les instructions if else en Python.
Sejal Jaiswal's photo

Sejal Jaiswal

Voir plusVoir plus