| 13.9 Fonctions et options à utiliser dans les clauses GROUP BY
 13 Fonctions à utiliser dans les clauses SELECT et WHERE
 Manuel de Référence MySQL 4.1 : Version Française
 
 . Fonctions avec GROUP BY
 ->Options de GROUP BY
 . GROUP BY avec les champs cachés
 
 
 | 
  13.9.2 Options de GROUP BY 
   
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
  : Le contenu de cette table peut être agrégé par année avec la clause
 
GROUP BY
  :| 
CREATE TABLE sales(
 year    INT NOT NULL,
 country VARCHAR(20) NOT NULL,
 product VARCHAR(32) NOT NULL,
 profit  INT
 );
 | 
 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.| 
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;+------+-------------+
 | year | SUM(profit) |
 +------+-------------+
 | 2000 |        4525 |
 | 2001 |        3010 |
 +------+-------------+
 | 
 
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 : 
 La ligne du grand total est identifiée par la valeur  
NULL
  dans la colonne
 
year
 .| 
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;+------+-------------+
 | year | SUM(profit) |
 +------+-------------+
 | 2000 |        4525 |
 | 2001 |        3010 |
 | NULL |        7535 |
 +------+-------------+
 | 
 
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 : 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;
 +------+---------+------------+-------------+
 | 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 |
 +------+---------+------------+-------------+
 | 
 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
  :| 
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 |
 +------+---------+------------+-------------+
 | 
 
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 : 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
 .| 
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 |
 +------+---------+------------+-------------+
 | 
 
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. |