Catégories :

Syntaxe de requête

GROUP BY ROLLUP

GROUP BY ROLLUP est une extension de la clause GROUP BY qui produit des lignes de sous-totaux (en plus des lignes groupées). Les lignes de sous-totaux sont des lignes qui s’agrégent encore, dont les valeurs sont dérivées en calculant les mêmes fonctions d’agrégation que celles qui ont été utilisées pour produire les lignes groupées.

Vous pouvez considérer le rollup comme la génération de plusieurs ensembles de résultats, dont chacun (après le premier) est l’agrégat de l’ensemble de résultats précédent. Ainsi, par exemple, si vous possédez une chaîne de magasins de détail, vous voudrez peut-être voir le bénéfice pour :

  • chaque magasin.

  • chaque ville (les grandes villes peuvent avoir plusieurs magasins).

  • chaque région.

  • tout (tous les magasins dans tous les régions).

Vous pouvez créer des rapports distincts pour obtenir cette information, mais il est plus efficace de numériser les données une seule fois.

Si vous êtes familier avec le concept des ensembles de groupement (GROUP BY GROUPING SETS), vous pouvez considérer un groupement ROLLUP comme équivalent à une série d’ensembles de groupement, ce qui est essentiellement une spécification plus courte. Les éléments N d’une spécification ROLLUP correspondent à N+1 GROUPING SETS.

Voir aussi :

GROUP BY GROUPING SETS

Syntaxe

SELECT ...
FROM ...
[ ... ]
GROUP BY ROLLUP ( groupRollup [ , groupRollup [ , ... ] ] )
[ ... ]

Où :

groupRollup ::= { <column_alias> | <position> | <expr> }
alias_colonne

Alias de colonne figurant dans la liste SELECT du bloc de requête.

position

Position d’une expression dans la liste SELECT.

expr

Toute expression sur les tables du périmètre actuel.

Notes sur l’utilisation

  • Comme la requête est agrégée à des niveaux de plus en plus élevés, elle affiche des valeurs NULL dans plus de colonnes de chaque ligne. C’est tout à fait approprié. Par exemple, dans l’exemple ci-dessous, pour l’agrégat au niveau de la région, la colonne ville est NULL. C’est parce que la valeur dans la colonne profit ne correspond pas à une ville. De même, dans le total final, qui regroupe les données de toutes les régions et de toutes les villes, les recettes ne proviennent pas d’une région ou d’une ville en particulier, de sorte que les colonnes région et ville dans cette ligne sont NULL.

  • La requête doit énumérer le « niveau le plus significatif » en premier entre parenthèses après ROLLUP. Par exemple, parce que les régions contiennent des villes, si vous cumulez des données entre régions et villes, la clause devrait être ...ROLLUP (State, City). Si vous inversez l’ordre des noms des colonnes, vous obtiendrez un résultat qui n’est probablement pas ce que vous voulez. Dans l’exemple ci-dessous, le résultat sera incorrect, du moins en partie parce que la Californie et Porto Rico ont toutes deux une ville nommée San José (« SJ »), et vous ne voulez probablement pas combiner les revenus des deux San Joses différents, sauf dans le total final de tous les revenus. (Le problème de combinaison des données de différentes villes portant le même nom aurait pu être évité en créant un ID unique pour chaque ville et en utilisant l’ID plutôt que le nom dans la requête).

Exemples

Commencez par créer et charger un tableau contenant des informations sur les ventes d’une chaîne de magasins ayant des succursales dans différentes villes et états ou régions/territoires.

-- Create some tables and insert some rows.
CREATE TABLE products (product_ID INTEGER, wholesale_price REAL);
INSERT INTO products (product_ID, wholesale_price) VALUES 
    (1, 1.00),
    (2, 2.00);

CREATE TABLE sales (product_ID INTEGER, retail_price REAL, 
    quantity INTEGER, city VARCHAR, state VARCHAR);
INSERT INTO sales (product_id, retail_price, quantity, city, state) VALUES 
    (1, 2.00,  1, 'SF', 'CA'),
    (1, 2.00,  2, 'SJ', 'CA'),
    (2, 5.00,  4, 'SF', 'CA'),
    (2, 5.00,  8, 'SJ', 'CA'),
    (2, 5.00, 16, 'Miami', 'FL'),
    (2, 5.00, 32, 'Orlando', 'FL'),
    (2, 5.00, 64, 'SJ', 'PR');

Exécutez une requête de rollup qui affiche les bénéfices par ville, état et total dans tous les états.

L’exemple ci-dessous montre une requête qui a trois « niveaux » :

  • chaque ville.

  • chaque région.

  • tous revenus confondus.

    SELECT state, city, SUM((s.retail_price - p.wholesale_price) * s.quantity) AS profit 
     FROM products AS p, sales AS s
     WHERE s.product_ID = p.product_ID
     GROUP BY ROLLUP (state, city)
     ;
    

    Sortie :

    SELECT state, city, SUM((s.retail_price - p.wholesale_price) * s.quantity) AS profit 
     FROM products AS p, sales AS s
     WHERE s.product_ID = p.product_ID
     GROUP BY ROLLUP (state, city)
     ;
    +-------+---------+--------+
    | STATE | CITY    | PROFIT |
    |-------+---------+--------|
    | CA    | SF      |     13 |
    | CA    | SJ      |     26 |
    | FL    | Miami   |     48 |
    | FL    | Orlando |     96 |
    | PR    | SJ      |    192 |
    | CA    | NULL    |     39 |
    | FL    | NULL    |    144 |
    | PR    | NULL    |    192 |
    | NULL  | NULL    |    375 |
    +-------+---------+--------+