PARTITIONNEMENT D'UNE RELATION
(ou GROUPEMENT)
Clause GROUP BY


DEFINITION

* PRINCIPE

- partitionnement horizontal d'une relation, selon les valeurs d'un attribut ou d'un groupe d'attributs qui est spécifié dans la clause GROUP BY

- la relation est (logiquement) fragmentée en groupes de tuples, où tous les tuples de chaque groupe ont la même valeur pour l'attribut (ou le groupe d'attributs) de partitionnement

* FONCTIONS SUR LES GROUPES

- application possible de fonctions à chaque groupe

* RESTRICTION SUR LES GROUPES

- application possible d'un critère de restriction sur les groupes obtenus

- clause HAVING

INTERET DU GROUPEMENT

1) "Donner pour le cru Jurançon la moyenne des degrés de ses vins "

SELECT Avg (DEG)

FROM VINS

WHERE CRU='Jurançon'

Attention, la requête suivante est syntaxiquement incorrecte (parce que son schéma n'est plus défini conformément au modèle relationnel) :

SELECT CRU, Avg (DEG)

FROM VINS

WHERE CRU='Jurançon'

2) On se pose la même question mais pour tous les crus et non pas seulement le Jurançon. Si on connait tous les crus de la base de données, on peut lancer une requête par cru sur le modèle précédent. L'inconvénient est qu'il va falloir pas mal de requêtes. Si on ne connait pas les crus cette solution ne fonctionne pas. Il faut alors absolument recourir au groupement (c'est donc là son principal intérêt) :

SELECT CRU, Avg (DEG)

FROM VINS

GROUP BY CRU

COMMENT SE CALCULE LA PARTITION ?

Si on reprend la requête précédente, le calcul peut se détailler selon les étapes suivantes :

- trier la relation selon les attributs de groupement

Regardons la requête suivante :

SELECT CRU, DEG

FROM VINS

ORDER BY CRU

- créer une sous-relation (ensemble de tuples ou partition) pour chaque paquet ayant même valeur sur l'attribut CRU (de façon générale sur l'ensemble des attributs de groupement)

- appliquer la clause SELECT sur chaque partition (dans notre exemple la valeur de CRU et la moyenne des degrés sur la partition). Par définition un tuple au plus est construit par partition (s'il y a une clause HAVING toutes les partitions ne sont pas forcément dans la réponse). Le nombre de tuples résultat est donc majoré par le nombre de partitions.

Cette clause SELECT ne peut être formée que d'un sous ensemble des attributs de groupement ainsi que n'importe quel agrégat exprimé sur la partition.

Comparons notre exemple avec des requêtes syntaxiquement voisines :

RESTRICTION SUR LES GROUPES

* CLAUSE WHERE

RESTRICTION SUR LES TUPLES D'UNE RELATION

* CLAUSE HAVING

RESTRICTION SUR LES GROUPES D'UNE RELATION OBTENUS PAR LA CLAUSE GROUP BY

* EXEMPLE

"Donner les crus et les moyennes de degré des vins associés, si aucun vin du cru considéré n'a de degré supérieur ou égal à 12"

SELECT CRU, AVG(DEG)

FROM VINS

GROUP BY CRU

HAVING Max(DEG) < 12

Que l'on peut comparer à la requête suivante :

SELECT CRU, AVG(DEG)

FROM VINS

WHERE DEG<12

GROUP BY CRU

qui donne pour chaque cru la moyenne des degrés des vins de degré inférieur à 12 (elle correspond à la requête initiale mais travaillant non pas sur la relation VINS toute entière, mais seulement les tuples de degré inférieur à 12).

EXEMPLE DE REQUETE ERRONNEE

SELECT CRU, NV, Avg(DEG)

FROM VIN

GROUP BY CRU

Résultat "attendu"

CRU        NVs          Avg(DEG)
Bordeaux   {1,3,6,10}   10.0

Chablis {5,7} 11.0

Jurançon {2,8,11} 13.0

Requête non valide en SQL !!!

l'attribut NV est multivalué par rapport à l'attribut de partitionnement CRU

=> la relation résultat n'est pas en première forme normale



© B. Defude - INT Evry