Les bases de données SQL stockent des milliers de lignes. Une requête GROUP BY regroupe ces lignes similaires en synthèses utiles alors que la clause SQL HAVING sélectionne uniquement les groupes qui répondent à des critères précis sur ces synthèses.
Table des matières
Syntaxe SQL de base pour la clause SQL HAVING
La clause HAVING filtre le résultat de la requête après un regroupement. Elle utilise des conditions sur les fonctions d’agrégation comme COUNT ou SUM. Cette condition apparaît toujours après GROUP BY et avant ORDER BY ce qui la place en quatrième position logique après FROM, WHERE et GROUP BY. L’ordre d’exécution traite HAVING après le regroupement effectif ce qui garantit que les conditions HAVING s’appliquent aux vraies synthèses.
SELECT COUNT(field1), field2
FROM table
GROUP BY field2
HAVING condition;
Exemples de requêtes plus complexes avec HAVING
Commandes SQL SELECT avec HAVING avec COUNT pour trier par le nombre de lignes
La requête suivante sélectionne les catégories contenant plus de 20 produits. HAVING élimine les catégories marginales du résultat.
SELECT categorie, COUNT(*) AS nb_produits
FROM produits
GROUP BY categorie
HAVING COUNT(*) > 20;
Créer une requête avec HAVING et SUM
Cette analyse met en évidence les mois les plus rentables. SUM calcule le chiffre d’affaires mensuel pour chaque groupe et HAVING ne garde que les performances supérieures à 50 000 euros.
SELECT mois, SUM(ventes) AS chiffre_affaires
FROM ventes_mensuelles
GROUP BY mois
HAVING SUM(ventes) > 50000;
Écrire des requêtes avec HAVING et AVG
Cette requête SQL identifie les régions à clientèle senior. AVG calcule l’âge moyen par groupe régional et HAVING sélectionne les zones pertinentes pour des produits spécifiques.
SELECT region, AVG(age) AS age_moyen
FROM clients
GROUP BY region
HAVING AVG(age) > 40;
Requête de sélection avec HAVING et MIN/MAX
Cette analyse repère les fournisseurs les moins chers. MIN détermine le prix le plus bas par fournisseur.
SELECT fournisseur, MIN(prix_unitaire) AS prix_min
FROM produits
GROUP BY fournisseur
HAVING MIN(prix_unitaire) < 10;
Erreurs fréquentes avec HAVING chez les débutants
Les débutants rencontrent souvent les mêmes obstacles avec HAVING. La première erreur place HAVING avant GROUP BY alors que l’ordre logique impose GROUP BY en troisième position et HAVING en quatrième. La base de données rejette immédiatement cette inversion
-- ❌ SYNTAXE FAUSSE
SELECT ville, COUNT(*)
FROM clients
HAVING COUNT(*) > 10
GROUP BY ville;
-- ✅ SYNTAXE CORRECTE
SELECT ville, COUNT(*)
FROM clients
GROUP BY ville
HAVING COUNT(*) > 10;
Une autre erreur est d’utiliser WHERE à la place de HAVING pour les agrégations. WHERE ne comprend pas les fonctions COUNT ou SUM appliquées à des groupes mais filtre des lignes individuelles avant regroupement. HAVING attend le résultat complet des groupes. Cette distinction détermine le choix de clause.
-- ❌ WHERE IMPOSSIBLE
SELECT ville, COUNT(*)
FROM clients
WHERE COUNT(*) > 10
GROUP BY ville;
-- ✅ HAVING REQUIS
SELECT ville, COUNT(*)
FROM clients
GROUP BY ville
HAVING COUNT(*) > 10;
MySQL déclenche parfois une erreur sql_mode ONLY_FULL_GROUP_BY avec HAVING. Ce mode strict vérifie les colonnes orphelines dans la requête de sélection. La solution consiste à ajouter toutes les colonnes non agrégées dans GROUP BY.
Bonnes pratiques HAVING professionnelles
Ajoutez toujours ORDER BY après HAVING pour trier les résultats logiquement. Les totaux agrégés apparaissent souvent dans l’ordre du stockage sans tri explicite et ORDER BY DESC classe les performances par importance décroissante.
La prochaine requête présente les catégories les plus rentables en premier et ORDER BY référence directement la fonction d’agrégation. Le classement facilite l’analyse immédiate des priorités.
SELECT categorie, SUM(ventes)
FROM produits
GROUP BY categorie
HAVING SUM(ventes) > 10000
ORDER BY SUM(ventes) DESC;
Créez des index sur les colonnes GROUP BY pour accélérer les regroupements. Un index trie automatiquement les valeurs avant GROUP BY ce qui réduit drastiquement le temps d’exécution sur de gros volumes.
Testez les requêtes HAVING par étapes progressivesen exécutant d’abord sans HAVING pour vérifier GROUP BY. Ajoutez ensuite HAVING pour valider le filtrage des groupes.
Utilisez des alias descriptifs pour les fonctions d’agrégation. COUNT(*) AS nb_total améliore la lisibilité du résultat. Les alias facilitent aussi les références dans ORDER BY et HAVING.
Exercices pratiques HAVING
Appliquez immédiatement les concepts appris avec ces exercices concrets.
Exercice 1 : Sélectionnez les catégories dans la Bdd avec plus de 100 ventes :
SELECT _________, _________(*)
FROM _________
GROUP BY _________
HAVING _________(*) > _________;
-- ✅SELECT categorie, COUNT(*)
FROM ventes
GROUP BY categorie
HAVING COUNT(*) > 100;
Exercice 2 : Corrigez cette erreur de syntaxe :
SELECT ville, COUNT(*)
FROM clients
HAVING COUNT(*) > 20 -- Problème ?
GROUP BY ville;
-- ✅SELECT ville, COUNT(*)
FROM clients GROUP BY ville
HAVING COUNT(*) > 20;
Sources: MySql , Postgresql