4th Jul 2022 7 minutes de lecture Qu'est-ce que la clause SQL GROUPING SETS, et comment l'utiliser ? Andrew Bone sql apprendre sql group by ORDER BY Table des matières Syntaxe des GROUPING SETS SQL Exemple de GROUPING SETS SQL Exemple de ROLLUP SQL Exemple de SQL CUBE Regroupez efficacement vos données avec les extensions SQL GROUP BY Les GROUPING SETS sont des groupes, ou ensembles, de colonnes permettant de regrouper des lignes. Au lieu d'écrire plusieurs requêtes et de combiner les résultats avec un UNION, vous pouvez simplement utiliser les GROUPING SETS. GROUPING SETS en SQL peut être considéré comme une extension de la clause GROUP BY. Elle vous permet de définir plusieurs ensembles de regroupement dans la même requête. Examinons sa syntaxe et comment elle peut être équivalente à une GROUP BY avec plusieurs clauses UNION ALL. Syntaxe des GROUPING SETS SQL La syntaxe générale de GROUPING SETS est la suivante : SELECT aggregate_function(column_1) column_2, column_3, FROM table_name GROUP BY GROUPING SETS ( (column_2, column_3), (column_2), (column_3), () ); Vous pouvez voir comment nous regroupons par les différents ensembles. Cette syntaxe est équivalente à la requête plus longue suivante qui utilise GROUP BY avec UNION ALL pour combiner les résultats : SELECT SUM(column_1), column_2, column_3 FROM table_name GROUP BY column_2, column_3 UNION ALL SELECT SUM(column_1), column_2, NULL FROM table_name GROUP BY column_2 UNION ALL SELECT SUM(column_1), NULL, column_3 FROM table_name GROUP BY column_3 UNION ALL SELECT SUM(column_1), NULL, NULL FROM table_name Si vous utilisez GROUP BY comme cela, vous avez besoin de plusieurs clauses UNION ALL pour combiner les données provenant de différentes sources. UNION ALL exige également que tous les ensembles de résultats aient le même nombre de colonnes avec des types de données compatibles, vous devez donc ajuster les requêtes en ajoutant une valeur NULL là où c'est nécessaire. Même si la requête fonctionne comme prévu, elle présente deux problèmes principaux : Elle est longue et pas très facile à gérer. Elle peut entraîner un problème de performances, car SQL doit analyser la table des ventes à chaque fois. La clause GROUPING SETS résout ces problèmes. Mais quel est son impact sur le résultat par rapport à une clause traditionnelle GROUP BY? Il est temps de regarder un exemple ! Exemple de GROUPING SETS SQL Nous avons besoin d'un échantillon de données. Créons une table appelée payments qui contient tous les paiements que notre entreprise a reçus en janvier, février et mars pour les quatre dernières années, de 2018 à 2021. Le magasin exact où le paiement a eu lieu est indiqué par la colonne store_id. Pour créer cette table, exécutez la requête suivante : CREATE TABLE payment (payment_amount decimal(8,2), payment_date date, store_id int); INSERT INTO payment VALUES (1200.99, '2018-01-18', 1), (189.23, '2018-02-15', 1), (33.43, '2018-03-03', 3), (7382.10, '2019-01-11', 2), (382.92, '2019-02-18', 1), (322.34, '2019-03-29', 2), (2929.14, '2020-01-03', 2), (499.02, '2020-02-19', 3), (994.11, '2020-03-14', 1), (394.93, '2021-01-22', 2), (3332.23, '2021-02-23', 3), (9499.49, '2021-03-10', 3), (3002.43, '2018-02-25', 2), (100.99, '2019-03-07', 1), (211.65, '2020-02-02', 1), (500.73, '2021-01-06', 3); Vous pouvez visualiser les données à l'aide de cette simple clause SELECT: SELECT * FROM payment ORDER BY payment_date; L'exécution de cette requête donne le résultat suivant : payment_amountpayment_datestore_id 1200.992018-01-181 189.232018-02-151 3002.432018-02-252 33.432018-03-033 7382.102019-01-112 382.922019-02-181 100.992019-03-071 322.342019-03-292 2929.142020-01-032 211.652020-02-021 499.022020-02-193 994.112020-03-141 500.732021-01-063 394.932021-01-222 3332.232021-02-233 9499.492021-03-103 Vous pouvez voir qu'il y a plusieurs entrées pour certains magasins. Imaginez que nous préparions un rapport et que nous voulions voir un total pour chaque magasin. La fonction d'agrégation SUM() peut nous y aider. Nous utiliserons également la clause GROUP BY pour regrouper nos résultats par année et par magasin. SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment GROUP BY YEAR(payment_date), store_id ORDER BY YEAR(payment_date), store_id; SUM(payment_amount)Payment YearStore 1390.2220181 3002.4320182 33.4320183 483.9120191 7704.4420192 1205.7620201 2929.1420202 499.0220203 394.9320212 13332.4520213 Les résultats sont agrégés par chaque combinaison unique d'année et de magasin. Cependant, nous ne pouvons pas voir les paiements totaux par année : les paiements totaux pour 2018, 2019, 2020 ou 2021. Nous ne pouvons pas non plus voir les totaux par magasin, ce qui serait une mesure utile à avoir. L'utilisation de GROUPING SETS nous permet de voir ces totaux. SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment_new GROUP BY GROUPING SETS (YEAR(payment_date), store_id) ORDER BY YEAR(payment_date), store_id; SUM(payment_amount)Payment YearStore 3079.89NULL1 14030.94NULL2 13864.90NULL3 4426.082018NULL 8188.352019NULL 4633.922020NULL 13727.382021NULL Wow, nos résultats ont radicalement changé ! Maintenant, nous ne voyons que les grands totaux pour chaque magasin ainsi que les grands totaux pour chaque année. Pour les colonnes pour lesquelles les lignes ne sont pas groupées, vous voyez les valeurs NULL. N'oubliez pas que vous pouvez inclure plusieurs clauses GROUP BY dans votre GROUPING SETS. En appliquant cela à notre requête, nous obtenons le résultat suivant : SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment_new GROUP BY GROUPING SETS ( (YEAR(payment_date), store_id), (YEAR(payment_date)), (store_id) ) ORDER BY YEAR(payment_date), store_id; SUM(payment_amount)Payment YearStore 3079.89NULL1 14030.94NULL2 13864.90NULL3 4426.082018NULL 1390.2220181 3002.4320182 33.4320183 8188.352019NULL 483.9120191 7704.4420192 4633.922020NULL 1205.7620201 2929.1420202 499.0220203 13727.382021NULL 394.9320212 13332.4520213 Avant de terminer ce tutoriel, nous devons mentionner deux autres extensions SQL GROUP BY qui pourraient s'avérer utiles pour votre projet ou scénario particulier : ROLLUP et CUBE. Ces sujets sont couverts de manière très détaillée dans ce parcours d'apprentissage SQL avancé de LearnSQL.fr qui présente les fonctions de fenêtre, les extensions GROUP BY et les requêtes récursives. Exemple de ROLLUP SQL Comme pour GROUPING SETS, vous pouvez utiliser l'option ROLLUP dans une seule requête pour générer plusieurs ensembles de regroupement. ROLLUP suppose une hiérarchie entre les colonnes d'entrée. Par exemple, si les colonnes en entrée sont : GROUP BY ROLLUP(column_1,column_2) la hiérarchie pour ceci est column_1 > column_2, et ROLLUP génère les ensembles de regroupement suivants : (column_1, column_2) (column_1) () ROLLUP génère tous les ensembles de regroupement qui ont un sens dans cette hiérarchie. Il génère une ligne de sous-total chaque fois que la valeur de column_1 change ; c'est la hiérarchie que nous avons fournie. Pour cette raison, nous utilisons souvent ROLLUP pour générer des sous-totaux et des totaux généraux dans les rapports. L'ordre de vos colonnes dans ROLLUP est très important. Examinons une requête qui utilise ROLLUP: SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment GROUP BY ROLLUP (YEAR(payment_date), store_id) ORDER BY YEAR(payment_date), store_id SUM(payment_amount)Payment YearStore 30975.73NULLNULL 4426.082018NULL 1390.2220181 3002.4320182 33.4320183 8188.352019NULL 483.9120191 7704.4420192 4633.922020NULL 1205.7620201 2929.1420202 499.0220203 13727.382021NULL 394.9320212 13332.4520213 Le grand total est affiché en haut du résultat : 30975.73NULLNULL Le reste du résultat est structuré comme suit. Tout d'abord, le total annuel est affiché : 4426.082018NULL Il est suivi par les totaux par magasin et par année : 1390.2220181 3002.4320182 33.4320183 Comme vous pouvez le constater, ROLLUP génère une ligne de sous-total chaque fois que la valeur de Payment Year change, puisque c'est la hiérarchie que nous avons fournie. Cet exemple montre à quel point ROLLUP peut être utile à des fins de reporting. Exemple de SQL CUBE Tout comme ROLLUP, CUBE est une extension de la clause GROUP BY. Elle vous permet de générer des sous-totaux pour toutes les combinaisons des colonnes de regroupement spécifiées dans la clause GROUP BY. La clause CUBE revient à combiner GROUPING SETS et ROLLUP. Elle affiche le résultat détaillé des deux. SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment GROUP BY CUBE (YEAR(payment_date), store_id) ORDER BY YEAR(payment_date), store_id SUM(payment_amount)Payment YearStore 30975.73NULLNULL 3079.89NULL1 14030.94NULL2 13864.90NULL3 4426.082018NULL 1390.2220181 3002.4320182 33.4320183 8188.352019NULL 483.9120191 7704.4420192 4633.922020NULL 1205.7620201 2929.1420202 499.0220203 13727.382021NULL 394.9320212 13332.4520213 La principale différence de cette sortie par rapport à l'exemple ROLLUP est que le total général pour chaque magasin est également affiché ici. 3079.89NULL1 14030.94NULL2 13864.90NULL3 À l'exception de ces lignes, toutes les lignes de ce résultat sont identiques à celles du résultat de ROLLUP. Ceci conclut notre comparaison de GROUPING SETS, ROLLUP, et CUBE! Vous trouverez d'autres exemples dans cet article sur le regroupement, le roulement et le cubage des données. Regroupez efficacement vos données avec les extensions SQL GROUP BY La maîtrise des extensions SQL GROUP BY demande de la pratique. Des options comme GROUPING SETS, ROLLUP et CUBE vous permettent de manipuler les résultats de vos requêtes de différentes manières. Savoir utiliser efficacement ces extensions réduit la nécessité de formater manuellement vos données avant de les transmettre aux parties prenantes concernées. Pour approfondir vos connaissances dans ce domaine, vous pouvez suivre ce cours sur les extensions GROUP BY à l'adresse LearnSQL.fr, qui couvre GROUPING SETS, ROLLUP et CUBE. Tags: sql apprendre sql group by ORDER BY