🚀 Novembre a commencé ! SQLtest.online reste gratuit grâce aux dons de personnes comme vous. Aidez-nous à atteindre l'objectif de ce mois plus tôt pour que le site fonctionne sans interruption. Soutenir maintenant →
Code SQL copié dans le presse-papiers

Filtrer les groupes avec HAVING

Leçon 4.3 · Temps de lecture: ~7 minutes · Exercices pratiques ↓

Quand vous utilisez GROUP BY avec les agrégations, vous devez souvent filtrer les groupes par leurs résultats agrégés. HAVING est l'opérateur pour filtrer les groupes, comme WHERE filtre les lignes individuelles. Dans cette leçon, vous apprendrez les différences entre WHERE et HAVING, la syntaxe et des exemples pratiques sur Sakila. À la fin, vous utiliserez HAVING avec assurance pour l'analyse approfondie des données.

Dans les leçons précédentes, vous avez appris GROUP BY pour grouper les données et appliquer les agrégations. Vient maintenant l'étape suivante: filtrer les groupes eux-mêmes par des conditions sur les valeurs agrégées.

HAVING fait cela en permettant des conditions après le regroupement.

SQL HAVING et WHERE : WHERE filtre les lignes avant le regroupement, HAVING filtre les groupes après ; HAVING SUM(amount) width= 100 garde 395 clients sur 599" width="100%">

WHERE vs HAVING

  • WHERE filtre les lignes avant le regroupement
  • HAVING filtre les groupes après l'agrégation
SELECT colonne1, COUNT(*) AS cnt
FROM table
WHERE colonne1 > 100          -- filtrer AVANT le regroupement
GROUP BY colonne1
HAVING COUNT(*) > 10;         -- filtrer APRÈS le regroupement

Syntaxe de HAVING

Structure de base:

SELECT colonne1, FONCTION_AGG(colonne2)
FROM table
GROUP BY colonne1
HAVING condition;

La condition en HAVING implique généralement une fonction d'agrégation.


Exemples avec une seule condition

Clients avec paiements totaux au-dessus de 100

SELECT customer_id, SUM(amount) AS total_paye
FROM payment
GROUP BY customer_id
HAVING SUM(amount) > 100;

Résultat: uniquement les clients dont les paiements totaux dépassent 100.

Employés ayant traité plus de 50 paiements

SELECT staff_id, COUNT(*) AS nb_paiements
FROM payment
GROUP BY staff_id
HAVING COUNT(*) > 50;

Résultat: employés avec plus de 50 paiements traités.

Clients avec paiement moyen >= 5

SELECT customer_id, AVG(amount) AS paiement_moyen
FROM payment
GROUP BY customer_id
HAVING AVG(amount) >= 5;

Résultat: clients dont le paiement moyen est d'au moins 5.


HAVING avec plusieurs conditions

Vous pouvez combiner les conditions avec AND et OR:

SELECT staff_id, COUNT(*) AS cnt, SUM(amount) AS total
FROM payment
GROUP BY staff_id
HAVING COUNT(*) > 50 AND SUM(amount) > 500;

Résultat: employés avec plus de 50 paiements ET total au-dessus de 500.

Avec l'opérateur OR

SELECT customer_id, COUNT(*) AS rentals, SUM(amount) AS paid
FROM payment
GROUP BY customer_id
HAVING COUNT(*) > 100 OR SUM(amount) > 1000;

Résultat: clients avec plus de 100 paiements OU total au-dessus de 1000.


Exemples pratiques

Catégories de films avec ventes au-dessus de 2000

SELECT category_id, SUM(p.amount) AS total_ventes
FROM payment p
JOIN rental r ON p.rental_id = r.rental_id
JOIN inventory i ON r.inventory_id = i.inventory_id
JOIN film_category fc ON i.film_id = fc.film_id
GROUP BY category_id
HAVING SUM(p.amount) > 2000;

Pays avec plus de 20 clients

SELECT country, COUNT(*) AS nb_clients
FROM customer cu
JOIN address a ON cu.address_id = a.address_id
JOIN city ci ON a.city_id = ci.city_id
JOIN country co ON ci.country_id = co.country_id
GROUP BY country
HAVING COUNT(*) > 20;

Employés avec un chiffre d'affaires quotidien supérieur à 500

SELECT staff_id, DATE(payment_date) AS date_paiement, SUM(amount) AS revenus_quotidiens
FROM payment
GROUP BY staff_id, DATE(payment_date)
HAVING SUM(amount) > 500;

Résultat : 56 lignes, chaque paire employé-jour où l'employé a encaissé plus de 500.


Questions fréquentes

Pourquoi ne puis-je pas utiliser WHERE au lieu de HAVING?

WHERE fonctionne avant le regroupement, il ne peut donc pas vérifier les fonctions d'agrégation. HAVING fonctionne après le regroupement et peut analyser les résultats d'agrégation (COUNT, SUM, AVG, etc.).

Puis-je utiliser une colonne non agrégée dans HAVING?

Oui, vous pouvez utiliser une colonne de GROUP BY, mais cela n'est généralement pas nécessaire. Par exemple, HAVING customer_id > 100 fonctionne, mais il est plus naturel d'écrire cela dans WHERE avant le regroupement.

HAVING peut-il être utilisé sans GROUP BY?

Techniquement dans certains SGBD c'est possible, mais c'est peu pratique car HAVING est conçu pour filtrer les groupes. Utilisez WHERE pour filtrer les lignes individuelles sans regroupement.


Questions d'entretien

Qu'est-ce que HAVING et en quoi diffère-t-il de WHERE?

HAVING filtre les groupes après agrégation, tandis que WHERE filtre les lignes avant regroupement. WHERE ne peut pas fonctionner avec les fonctions d'agrégation, mais HAVING fonctionne uniquement avec elles.

Puis-je utiliser WHERE et HAVING ensemble dans une requête?

Oui, c'est même recommandé. WHERE filtre les lignes avant regroupement et HAVING filtre les groupes après. Par exemple, WHERE amount > 10 GROUP BY customer_id HAVING SUM(amount) > 100 exclut d'abord les petits paiements, puis regroupe et filtre les groupes.

Quel est l'ordre d'exécution: WHERE ou HAVING?

WHERE est appliqué en premier (avant GROUP BY), puis GROUP BY effectue le regroupement, puis HAVING filtre les groupes résultants, et enfin ORDER BY et LIMIT sont appliqués.


Points clés de cette leçon:

  • HAVING filtre les groupes après agrégation, WHERE filtre les lignes avant regroupement.
  • HAVING est utilisé avec les fonctions d'agrégation (COUNT, SUM, AVG, MIN, MAX).
  • Vous pouvez combiner plusieurs conditions dans HAVING en utilisant AND/OR.
  • Souvent WHERE et HAVING fonctionnent ensemble: WHERE exclut les lignes inutiles, HAVING filtre les groupes.
  • HAVING permet des requêtes analytiques profondes avec filtrage au niveau du groupe.

Essayez de resoudre les exercices suivants pour consolider ce que vous avez appris dans cette lecon.

  1. Prénoms d'acteurs en double
  2. Catégories avec films longs en moyenne
  3. Quelle est la différence entre HAVING et WHERE ?
  4. Acteurs homonymes
  5. Films les plus retardés