GROUP BY et HAVING : le groupement de données



Je vous disais un peu plus tôt qu'on ne pouvait pas récupérer d'autres champs lorsqu'on utilisait une fonction d'agrégat. Prenons par exemple la requête suivante :

Code : PHP

1

SELECT AVG(prix) AS prix_moyen, console FROM jeux_video



Ça n'a pas de sens de récupérer le prix moyen de tous les jeux et le champ « console » à la fois. Il n'y a qu'un seul prix moyen pour tous les jeux, mais plusieurs consoles. MySQL ne peut pas renvoyer un tableau correspondant à ces informations-là.


GROUP BY : grouper des données



En revanche, ce qui pourrait avoir du sens, ce serait de demander le prix moyen des jeux pour chaque console ! Pour faire cela, on doit utiliser un nouveau mot-clé : GROUP BY. Cela signifie « grouper par ». On utilise cette clause en combinaison d'une fonction d'agrégat (commeAVG) pour obtenir des informations intéressantes sur des groupes de données.

Voici un exemple d'utilisation de GROUP BY :

Code : PHP 

1

SELECT AVG(prix) AS prix_moyen, console FROM jeux_video GROUP BY console



Il faut utiliser GROUP BY en même temps qu'une fonction d'agrégat, sinon il ne sert à rien. Ici, on récupère le prix moyen et la console, et on choisit de grouper par console. Par conséquent, on obtiendra la liste des différentes consoles de la table et le prix moyen des jeux de chaque plate-forme !

prix_moyen

console

12.67

Dreamcast

5.00

Gameboy

47.50

GameCube



Cette fois les valeurs sont cohérentes ! On a la liste des consoles et le prix moyen des jeux associés.

Exercice : essayez d'obtenir de la même façon la valeur totale des jeux que possède chaque personne.


HAVING : filtrer les données regroupées


HAVING est un peu l'équivalent de WHERE, mais il agit sur les données une fois qu'elles ont été regroupées. C'est donc une façon de filtrer les données à la fin des opérations.

Voyez la requête suivante :

Code : PHP

1

SELECT AVG(prix) AS prix_moyen, console FROM jeux_video GROUP BY console HAVING prix_moyen <= 10



Avec cette requête, on récupère uniquement la liste des consoles et leur prix moyen si ce prix moyen ne dépasse pas 10 euros.

HAVING ne doit s'utiliser que sur le résultat d'une fonction d'agrégat. Voilà pourquoi on l'utilise ici sur prix_moyen et non sur console.

Je ne comprends pas la différence entre WHERE et HAVING. Les deux permettent de filtrer, non ?



Oui, mais pas au même moment. WHERE agit en premier, avant le groupement des données, tandis que HAVING agit en second, après le groupement des données. On peut d'ailleurs très bien combiner les deux, regardez l'exemple suivant :

Code : PHP 

1

SELECT AVG(prix) AS prix_moyen, console FROM jeux_video WHERE possesseur='Patrick' GROUP BY console HAVING prix_moyen <= 10


Ça commence à faire de la requête maousse costaude. ;-)
Ici, on demande à récupérer le prix moyen par console de tous les jeux de Patrick (WHERE), à condition que le prix moyen des jeux de la console ne dépasse pas 10 euros (HAVING).

Créé avec HelpNDoc Personal Edition: Créer des documents d'aide facilement