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 de lecture

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

Certification disponible

Cours

Introduction à SQL

2 hr
838.8K
Apprenez à créer et à interroger des bases de données relationnelles à l'aide de SQL en seulement deux heures.
Afficher les détailsRight Arrow
Commencer le cours
Voir plusRight Arrow
Apparenté

blog

Les 20 meilleures questions d'entretien pour les flocons de neige, à tous les niveaux

Vous êtes actuellement à la recherche d'un emploi qui utilise Snowflake ? Préparez-vous à répondre à ces 20 questions d'entretien sur le flocon de neige pour décrocher le poste !
Nisha Arya Ahmed's photo

Nisha Arya Ahmed

20 min

blog

Q2 2023 DataCamp Donates Digest

DataCamp Donates a offert plus de 20k bourses d'études à nos partenaires à but non lucratif au deuxième trimestre 2023. Découvrez comment des apprenants défavorisés et assidus ont transformé ces opportunités en réussites professionnelles qui ont changé leur vie.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

blog

Célébration de Saghar Hazinyar : Une boursière de DataCamp Donates et une diplômée de Code to Inspire

Découvrez le parcours inspirant de Saghar Hazinyar, diplômée de Code to Inspire, qui a surmonté les défis en Afghanistan et s'est épanouie grâce à une bourse de DataCamp Donates.
Fereshteh Forough's photo

Fereshteh Forough

4 min

blog

2022-2023 Rapport annuel DataCamp Classrooms

À l'aube de la nouvelle année scolaire, DataCamp Classrooms est plus motivé que jamais pour démocratiser l'apprentissage des données, avec plus de 7 650 nouveaux Classrooms ajoutés au cours des 12 derniers mois.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

8 min

blog

Nous avons fait don de bourses DataCamp Premium à un million de personnes, et ce n'est pas fini.

Réparties entre nos deux programmes d'impact social, DataCamp Classrooms et #DCDonates, les bourses offrent un accès illimité à tout ce que DataCamp Premium a à offrir.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

Voir plusVoir plus