Depuis MySQL 4.1.1, la clause GROUP BY
permet
l'utilisation de l'option WITH ROLLUP
qui
fait que des lignes supplémentaires seront ajoutées lors de
regroupements. Ces lignes représentent des regroupements de
haut niveau (ou des super-agrégats). ROLLUP
vous permet de répondre simultanément à plusieurs niveaux
d'analyse avec une seule requête. Il peut être utilisée, par
exemple, pour supporter des opérations OLAP
(Online Analytical Processing
).
Voici une illustration. Supposons que vous ayez une table de
ventes sales
, avec des colonnes pour l'année
year
, le pays country
, le
produit product
et le profit
profit
:
CREATE TABLE sales ( year INT NOT NULL, country VARCHAR(20) NOT NULL, product VARCHAR(32) NOT NULL, profit INT );
Le contenu de cette table peut être agrégé par année avec la
clause GROUP BY
:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
+------+-------------+
Cette requête affiche le profit par année, mais si vous voulez déterminer le profit total de toutes les années, vous devez ajouter ces valeurs vous-mêmes, ou faire une autre requête.
Ou alors, vous pouvez utiliser la clause
ROLLUP
, qui fournit les deux niveaux
d'analyse dans la même requête. En ajoutant l'option
WITH ROLLUP
à la clause GROUP
BY
, la requête va produire une autre ligne, avec le
grand total de toutes les années :
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
| NULL | 7535 |
+------+-------------+
La ligne du grand total est identifiée par la valeur
NULL
dans la colonne year
.
ROLLUP
a des effets plus complexes lorsqu'il
y a plusieurs colonnes dans la clause GROUP
BY
. Dans ce cas, il a y un changement de valeur pour
toutes sauf la dernière colonne de groupement, et la requête
va produire les super-agrégats.
Par exemple, sans la clause ROLLUP
, le
résumé des ventes de la table sales
basé
sur l'année year
, le pays
country
et le produit
product
peut ressembler à ceci :
mysql>SELECT year, country, product, SUM(profit)
->FROM sales
->GROUP BY year, country, product;
+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2001 | Finland | Phone | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | +------+---------+------------+-------------+
Le résultat indique les valeurs résumées pour chaque triplet
année/pays/produit. Si nous ajoutons la clause
ROLLUP
, la requête produit plusieurs
nouvelles lignes :
mysql>SELECT year, country, product, SUM(profit)
->FROM sales
->GROUP BY year, country, product WITH ROLLUP;
+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | India | NULL | 1350 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2000 | USA | NULL | 1575 | | 2000 | NULL | NULL | 4525 | | 2001 | Finland | Phone | 10 | | 2001 | Finland | NULL | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | | 2001 | USA | NULL | 3000 | | 2001 | NULL | NULL | 3010 | | NULL | NULL | NULL | 7535 | +------+---------+------------+-------------+
Pour cette requête, ajouter ROLLUP
fait que
la requête ajoute les résumés de quatre niveaux d'analyse, et
non pas un seul. Voici comment interpréter le résultat de la
clause ROLLUP
:
Après chaque jeu de ligne sur les produits, pour une année
et un pays donnée, un résumé est ajouté, indiquant le
total de tous les produits. Ces lignes voient leur colonne
product
contenir la valeur
NULL
.
Après chaque jeu de ligne couvrant une année
particulière, une nouvelle ligne est ajoutée pour afficher
le total de tous les pays et produits, pour cette année la.
Ces lignes voient leurs colonnes country
et products
contenir
NULL
.
Finalement, suivant toutes les autres lignes, un résumé
général est produit, avec le grand total de toutes les
années, pays et produits. Cette ligne contient la valeur
NULL
pour toutes les colonnes
year
, country
et
products
.
Autres considérations avec
ROLLUP
Voici quelques comportements spécifiques de MySQL et son
implémentation de ROLLUP
:
Lorsque vous utilisez ROLLUP
, vous ne pouvez
pas utiliser de clause ORDER BY
pour trier
les résultats. En d'autres termes, ROLLUP
et
ORDER BY
sont mutuellement exclusives.
Toutefois, vous avec toujours le contrôle sur l'ordre de tri
avec la clause GROUP BY
. Vous pouvez utiliser
explicitement les mots ASC
et
DESC
avec les colonnes listées dans
GROUP BY
pour spécifier les ordres de tri
des colonnes individuelles. Les lignes de résumés de
ROLLUP
apparaissent toujours après les
lignes pour lesquelles ils sont calculés, quelque soit le tri.
La clause LIMIT
peut être utilisée pour
restreindre le nombre de lignes retournées au client.
LIMIT
s'applique après
ROLLUP
, et la limite s'appliquera aux lignes
ajoutées par ROLLUP
. Par exemple :
mysql>SELECT year, country, product, SUM(profit)
->FROM sales
->GROUP BY year, country, product WITH ROLLUP
->LIMIT 5;
+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | +------+---------+------------+-------------+
Notez qu'utiliser LIMIT
avec
ROLLUP
peut conduire à des résultats plus
difficiles à interpréter, car vous avez moins de contexte pour
comprendre les résumés.
Les indicateurs NULL
de chaque super-agrégat
sont produits lorsque la ligne est envoyée au client. Le
serveur recherche les colonnes citées dans la clause
GROUP BY
, en les prenant la plus à gauche,
dont la valeur change. Toute colonne du jeu de résultat dont le
nom ne correspond pas lexicalement à un de ces noms, verra sa
valeur être NULL
. Si vous spécifiez un
groupement par numéro de colonne, le serveur identifiera aussi
les colonnes qui devront recevoir NULL
.
Comme les valeurs NULL
des résumés sont
placées dans le résultat aussi tard durant le traitement de la
requête, nous ne pouvons pas les tester comme étant des
valeurs NULL
provenant de la requête
elle-même. Par exemple, vous ne pourrez pas ajouter
HAVING product IS NULL
pour éliminer
certains résumés qui ne vous intéressent pas.
D'un autre coté, les valeurs NULL
apparaissent comme des valeurs NULL
du coté
du client, et peuvent être repérées en tant que telles par le
client MySQL.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.