WHERE filtre les lignes avant l'exécution des regroupements et des agrégations, c'est-à-dire qu'il détermine quelles entrées seront incluses dans le regroupement/l'agrégation. HAVING filtre les groupes après l'application des fonctions d'agrégation.
Exemple :
-- Obtenir les départements avec un salaire total supérieur à 50000, en excluant les employés licenciés SELECT department, SUM(salary) as total FROM employees WHERE status = 'active' GROUP BY department HAVING SUM(salary) > 50000;
Ici :
Peut-on utiliser des fonctions d'agrégation dans WHERE ?
Erreur : on essaie d'écrire WHERE SUM(amount) > 100, mais ce n'est pas possible — les fonctions d'agrégation ne peuvent être appliquées QUE dans HAVING.
Exemple (INCORRECT) :
SELECT customer_id, SUM(amount) FROM orders WHERE SUM(amount) > 100 GROUP BY customer_id -- ERREUR : utilisation incorrecte de SUM() dans WHERE
Correct :
SELECT customer_id, SUM(amount) FROM orders GROUP BY customer_id HAVING SUM(amount) > 100;
Histoire
Développement d'un CRM. Tentative de filtrer les clients avec plus de 5 commandes via WHERE COUNT(order_id) > 5. La requête ne fonctionnait pas. Résultat : le nombre de clients dans le rapport était incorrect, car COUNT ne peut pas être utilisé dans WHERE.
Histoire
Analyse commerciale. Au lieu de filtrer les produits inactifs dans WHERE, ils ont utilisé HAVING. Résultat : agrégation de groupes "vides" et SQL lent. Corrigé en déplaçant le filtre de statut dans WHERE.
Histoire
Rapport complexe. Utilisation de HAVING sans GROUP BY pour filtrer des lignes individuelles. Dans certaines SGBD, cela génère une erreur, dans d'autres, un comportement peu clair. Conclusion : HAVING doit être après le regroupement et pour les conditions d'agrégation.