
WHERE filtre les lignes avant le regroupement ; HAVING filtre les groupes après un GROUP BY. La règle d’or : utilisez WHERE pour les conditions sur les colonnes, et HAVING uniquement pour les conditions sur des fonctions d’agrégation (SUM, COUNT, AVG…). Voici la différence en détail, avec exemples Oracle.
L’ordre d’exécution explique tout
Oracle traite une requête dans cet ordre logique : FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. Donc :
- WHERE agit avant le GROUP BY → il filtre les lignes individuelles.
- HAVING agit après le GROUP BY → il filtre les groupes déjà constitués.
Exemple côte à côte
-- WHERE : ne garder que les ventes 2026, puis regrouper
SELECT vendeur, SUM(montant) AS total
FROM ventes
WHERE EXTRACT(YEAR FROM date_vente) = 2026
GROUP BY vendeur;
-- HAVING : regrouper, puis ne garder que les vendeurs > 10000
SELECT vendeur, SUM(montant) AS total
FROM ventes
GROUP BY vendeur
HAVING SUM(montant) > 10000;Les combiner (le cas réel le plus fréquent)
SELECT vendeur, SUM(montant) AS total
FROM ventes
WHERE EXTRACT(YEAR FROM date_vente) = 2026 -- filtre les lignes
GROUP BY vendeur
HAVING SUM(montant) > 10000 -- filtre les groupes
ORDER BY total DESC;WHERE réduit d’abord le volume (plus performant), puis HAVING ne garde que les groupes voulus.
L’erreur classique à éviter
-- ❌ une agrégation dans WHERE → erreur (ORA-00934)
SELECT vendeur FROM ventes WHERE SUM(montant) > 10000 GROUP BY vendeur;
-- ✅ une agrégation va dans HAVING
SELECT vendeur FROM ventes GROUP BY vendeur HAVING SUM(montant) > 10000;On ne peut pas mettre SUM(), COUNT()… dans WHERE : elles n’existent qu’après le regroupement.
Performance : filtrez tôt avec WHERE
Chaque condition qui peut être exprimée en WHERE doit l’être : elle réduit le nombre de lignes avant le coûteux GROUP BY. Réservez HAVING aux seules conditions portant sur les agrégats.
Récapitulatif
- Condition sur une colonne (ville, date, statut) → WHERE.
- Condition sur un agrégat (SUM, COUNT, AVG, MAX…) → HAVING.
- HAVING s’utilise (presque) toujours avec GROUP BY.
Pour approfondir : nos tutoriels WHERE, GROUP BY et HAVING.
FAQ
Peut-on utiliser HAVING sans GROUP BY ?
Techniquement oui (la table entière est alors un seul groupe), mais c’est rare et peu lisible. HAVING va presque toujours de pair avec GROUP BY.
Pourquoi mettre une condition de date dans WHERE et pas HAVING ?
Parce que la date est une colonne, pas un agrégat : WHERE la filtre avant le regroupement, ce qui est plus rapide et logique.
HAVING peut-il utiliser un alias du SELECT ?
En Oracle, non de façon fiable : répétez l’expression d’agrégat (HAVING SUM(montant) > 10000) plutôt que l’alias.
