Parfois, la condition de restriction de WHERE ne suffit pas et on aimerait faire une restriction sur le résultat d'un agrégat (count, sum ou avg).
Or on ne peut pas utiliser d'agrégat dans WHERE car la restriction (WHERE) traite les enregistrement des tables AVANT la projection (SELECT champs).
SQL résoud ce problème en utilisant la clause HAVING qui permet de faire des sélections APRES le choix des champs dans l'exécution de la requête.
Voici trois exemples pour comprendre :
1. Exemple détaillé
Quels sont les clients qui ont moins de 10 commandes en 2004 ?
A priori, c'est un comptage des commandes groupé par numéro de client.
[sql]
SELECT numClient, count(*) as NbCde
FROM commande
WHERE YEAR(dateCde) = 2004
GROUP BY numClient
Cependant, ici, on affiche tous les clients sans distinction des résultats.
Il faut faire une sélection sur un comptage (count(*)>2)or on ne peut pas utiliser COUNT() dans WHERE**,
Tentons la requête suivante qui renvoie une erreur !!!
[sql]
SELECT numClient, count(*) AS NbCde
FROM commande
WHERE YEAR(dateCde) = 2004
AND COUNT(*) < 10 -- ERREUR , pas de count() dans WHERE, le champ projeté est un calcul
GROUP BY numClient
Noter que la requête suivante renvoie aussi une erreur !!!
[sql]
SELECT numClient, count(*) AS NbCde
FROM commande
WHERE YEAR(dateCde) = 2004
AND NbCde(*) < 10 -- ERREUR , pas de count() dans WHERE, le champ projeté n'existe pas dans les tables
GROUP BY numClient
Il faut impérativement utiliser HAVING pour ajouter une sélection sur le comptage
[sql]
SELECT nomVille, count(*) FROM client
WHERE YEAR(dateCde) = 2004
HAVING COUNT(*) < 10 -- ici c'est bon, on fait une restriction sur le résultat de la projection
GROUP BY nomVille
2. Exemple
Afin de faire une analyse de zone de chalandise, on souhaiterai savoir quelles sont les villes dont le nombre de clients est supérieur à 1 ?
C'est un comptage groupé par ville avec HAVING pour ajouter une restriction sur le comptage
[sql]
SELECT nomVille, count(*) FROM client
HAVING COUNT(*) > 1
GROUP BY nomVille
3ème. Exemple
Effectuons la même chose avec le chiffre d'affaire 2004 des clients : quels sont les numéro des clients qui ont un chiffre d'affaire supérieur à 1000EUR ?
Calculons le CA par numCli :
- on a 3 tables, donc 2 jointures,
- plus un calcul
Pas de problème, on suit le chemin des clés étrangères vers les clés primaires entre les tables et on fait toutes les jointures
[sql]
SELECT numCli, sum(qty*prixHTArt) AS CAHTCli
FROM contenir
JOIN commande ON contenir.numCde = commande.numCde -- prmière jointure
JOIN article ON contenir.refArt = article.refArt -- seconde jointure
WHERE YEAR(dateCde) = 2004 -- la restriction normale
HAVING sum(qty*prixHTArt) > 1000 -- la restriction supplémentaire
GROUP BY numCde