HAVING
HAVING filtre les groupes après le calcul des agrégats, là où WHERE filtre les lignes avant. On l'utilise pour garder, par exemple, les clients ayant passé au moins deux commandes.
- filtrer groupes
- post-agrégation
- WHERE vs HAVING
Syntaxe
SELECT col, COUNT(*)FROM tableWHERE condition_sur_les_lignesGROUP BY colHAVING COUNT(*) > 5;Exemple
SELECT c.name, COUNT(*) AS nb_commandesFROM orders oJOIN customers c ON c.id = o.customer_idWHERE o.status <> 'annulé'GROUP BY c.id, c.nameHAVING COUNT(*) >= 2;-- Jeu de données : boutique-- Résultat attendu :-- Lucas Martin | 2À retenir
- Ordre logique complet : FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT. HAVING voit donc les groupes, mais pas encore les alias du SELECT.
- Filtrez le plus tôt possible : une condition sur une colonne ordinaire (statut, date) va dans WHERE, ce qui réduit le nombre de lignes à regrouper. HAVING ne sert qu'aux conditions sur des agrégats.
- Piège : HAVING nb_commandes >= 2, avec l'alias, fonctionne dans SQLite et MySQL, mais PostgreSQL et SQL Server le refusent. Répétez l'agrégat, comme dans l'exemple, pour rester portable.
- Un HAVING sans GROUP BY traite toute la table comme un seul groupe : SELECT COUNT(*) FROM orders HAVING COUNT(*) > 3 renvoie une ligne ou aucune.
Voir aussi
- COUNT & GROUP BYGROUP BY range les lignes en groupes selon une ou plusieurs colonnes, puis COUNT, SUM ou AVG calculent une valeur par groupe. On obtient un tableau de synthèse, une ligne par groupe.
- WHEREWHERE ne garde que les lignes qui vérifient une condition, avant tout regroupement. C'est le filtre de base pour cibler un client, une période, un statut ou une plage de valeurs.
- Ordre logique d'exécutionUne requête ne s'évalue pas dans l'ordre où on l'écrit : FROM vient d'abord, SELECT presque à la fin. Connaître cet ordre explique la plupart des erreurs d'alias et d'agrégats.