Retour à la liste des articles Articles
5 minutes de lecture

HAVING ou WHERE en SQL : Ce que vous devez savoir

Cet article porte sur les clauses WHERE et HAVING de SQL. Ces deux clauses font partie des fondements de la commande SQL SELECT. Elles ont des utilisations similaires, mais il existe également des différences importantes que toute personne qui utilise SQL devrait connaître. Voyons ce qui se cache derrière le débat entre les clauses HAVING et WHERE.

Dans cet article, nous supposerons que nous travaillons pour une agence sociale gouvernementale qui soutient les personnes ou les familles dont le revenu est inférieur à un certain seuil. Cet organisme utilise plusieurs paramètres pour identifier les personnes ou les familles qui ont besoin d'aide.

Tout d'abord, examinons l'ensemble de données de l'échantillon. Puis, dans la suite de l'article, nous créerons des requêtes basées sur cet ensemble de données.

Exemple d'ensemble de données

Cet ensemble de données décrit des personnes appartenant à quatre familles qui vivent dans deux villes. Pour des raisons de simplicité, nous supposerons que last_name identifie la famille. L'idée est d'obtenir des métriques au niveau de la personne et au niveau de la famille.

TABLE Persons

namelast_namebirth_dateyear_incomecity
MaryRoberts1964-01-1178000Oklahoma
PeterRoberts1962-09-2586500Oklahoma
JohnRoberts1999-06-030Oklahoma
SueRoberts1996-03-060Oklahoma
MelindaRoberts1998-04-040Oklahoma
GeorgeHudson1953-02-2348000Oklahoma
NancyHudson1958-12-0665000Oklahoma
AnnHudson1979-04-0235000Oklahoma
CarlGibson1963-04-03102800Phoenix
LiGibson1963-12-2796000Phoenix
KateBishop1994-07-10920000Phoenix
MarkBishop2018--9-130Phoenix

D'accord. Maintenant que nous avons vu l'ensemble de données, commençons !

WHERE et HAVING : exemples simples

En termes simples, les clauses WHERE et HAVING agissent comme des filtres ; elles suppriment du résultat final d'une requête les enregistrements ou les données qui ne répondent pas à certains critères. Toutefois, elles s'appliquent à des ensembles de données différents. C'est le point important à comprendre entre WHERE et HAVING : WHERE filtre au niveau de l'enregistrement, tandis que HAVING filtre au niveau du "groupe d'enregistrements".

Voyons quelques exemples.

Voici un exemple de requête qui utilise la clause WHERE : Supposons que nous voulions obtenir les noms des personnes dont le revenu annuel est supérieur à 100 000 dollars. Nous devons filtrer (ou rejeter) au niveau de l'enregistrement, nous utiliserons donc la clause WHERE au lieu de la clause HAVING pour cette requête :

Texte de la requête à des fins de copier-coller :

SELECT name, last_name
FROM  persons
WHERE year_income > 100000;

WHERE et HAVING

Essayons maintenant une requête similaire, mais cette fois avec la clause HAVING : Supposons que nous voulions obtenir le site last_name des familles dont le revenu du ménage (c'est-à-dire la somme des revenus de tous les membres de la famille) est supérieur à 100 000 dollars. Il s'agit d'un cas évident d'utilisation de la clause HAVING, car nous n'avons pas besoin de filtrer par enregistrement. (Nous n'allons pas écarter l'enregistrement d'une personne parce qu'elle gagne moins de 100 000 $). L'idée est de filtrer en fonction du revenu familial, nous devons donc regrouper les personnes par last_name et utiliser HAVING pour filtrer les groupes de personnes, comme indiqué ci-dessous :

Texte de la requête à des fins de copier-coller :

SELECT 	last_name,
		SUM(year_income) AS "family_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income) > 100000;

WHERE et HAVING

CLAUSES COMPLEXES D'AVOIR

Nous pouvons utiliser autant de fonctions d'agrégation que nous le souhaitons dans la condition de la clause HAVING. Allons plus loin dans notre analyse des revenus des familles et calculons le revenu moyen par membre pour chaque famille. Nous voulons identifier les familles qui gagnent moins de 50 000 par personne. D'un point de vue économique, cette analyse peut en dire plus sur les revenus des familles que la précédente. Voici la requête :

Texte de la requête à des fins de copier-coller :

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income)  / COUNT(*) < 50000;

WHERE et HAVING

Remarque : la clause HAVING comporte certaines restrictions ; l'une d'elles est que les colonnes de niveau enregistrement dans la condition HAVING doivent également apparaître dans la clause GROUP BY.

Utilisation de WHERE et HAVING dans la même requête SQL

Il est très courant d'utiliser WHERE et HAVING dans la même requête. Effectuons une requête pour obtenir le revenu familial total et le revenu par membre pour les familles de l'Oklahoma comptant plus de quatre membres :

Texte de la requête à des fins de copier-coller :

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
WHERE city = ‘Oklahoma’
GROUP BY last_name
HAVING COUNT(*) > 4;

WHERE et HAVING

WHERE et HAVING dans les requêtes complexes

Pour conclure cet article, nous allons construire une requête qui renvoie les familles dont le revenu familial est inférieur au revenu moyen de leur ville. La partie la plus délicate est la sous-requête qui permet d'obtenir le revenu moyen pour une ville donnée. Veuillez noter que nous utilisons une requête différente car il s'agit du revenu moyen par ville; il n'est pas basé sur le nombre de membres par famille, mais sur le nombre de familles dans cette ville, tel que calculé avec count(distinct last_name).

Texte de la requête à des fins de copier-coller :

SELECT
  last_name, 
  COUNT(*) AS "members", 
  SUM(year_income) AS "family_income",
  SUM(year_income) / COUNT(*) AS "per_member_income"
FROM persons p
GROUP BY last_name
HAVING SUM(year_income) < (
  SELECT 
  SUM(year_income) / COUNT(distinct last_name) 
  FROM persons 
  WHERE city = p.city
);
WHERE et HAVING

Résolu : WHERE vs. HAVING en SQL

Nous avons examiné plusieurs requêtes différentes qui utilisent les clauses WHERE et HAVING de SQL. Comme nous l'avons mentionné, les deux clauses fonctionnent comme des filtres, mais chacune s'applique à un niveau de données différent. La clause WHERE filtre au niveau de l'enregistrement, tandis que la clause HAVING filtre au niveau du groupe.

SQL est un langage très souple et vous pouvez créer des millions de combinaisons à l'aide des clauses WHERE et HAVING. À ce stade, j'aimerais mentionner un excellent cours lié aux sujets abordés dans cet article : Création de rapports basiques en SQL in SQL de LearnSQL. Il s'adresse aux personnes qui connaissent les bases de SQL et qui souhaitent améliorer leurs compétences en matière de création de rapports SQL significatifs. Allez plus loin - explorez SQL !