“Aaaah j’ai encore une erreur parce que j’ai oublié d’ajouter mon nouveau champ dans mon GROUP BY et comme en plus j’ai l’habitude de mettre des numéros et de ne pas mettre mes fonctions d’agrégat en dernières….”
Prendre les bonnes habitudes d’écriture de requêtes SQL est important pour éviter quelques désagréments et aller plus vite.
Malgré tout, s’il est possible d’éviter de penser à certaines choses afin d’aller plus vite, c’est toujours le bienvenu.
Longue introduction pour présenter une simplification de la clause GROUP BY sur BigQuery (peut être dans d’autres systèmes) avec la disponibilité du GROUP BY ALL.
Avec cette clause, plus besoin de maintenir les champs de son GROUP BY lorsque l’on fait évoluer les colonnes du SELECT.
Exemple
WITH cte_data AS (
SELECT '2024-10-15' AS day, 'Site A' AS site, 1500 AS turnover UNION ALL
SELECT '2024-10-15' AS day, 'Site A' AS site, 1900 AS turnover UNION ALL
SELECT '2024-10-15' AS day, 'Site B' AS site, 2500 AS turnover UNION ALL
SELECT '2024-10-15' AS day, 'Site B' AS site, 1700 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site A' AS site, 1800 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site A' AS site, 2200 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site B' AS site, 2300 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site B' AS site, 2100 AS turnover
)
SELECT
day,
site,
SUM(turnover) AS turnoverTotal
FROM cte_data
GROUP BY
day,
site
;
Résultats
day | site | turnoverTotal |
2024-10-15 | Site A | 3400 |
2024-10-15 | Site B | 4200 |
2024-10-16 | Site A | 4000 |
2024-10-16 | Site B | 4400 |
Dans ces données nous avons 8 lignes qui suivent les ventes quotidiennes des sites A et B.
J’ai voulu suivre avoir de la visibilité sur leurs chiffres d’affaires quotidiens respectifs.
Une simple SUM() sur le chiffre d’affaires et un groupement sur le jour et le site.
Maintenant, je souhaite ajouter une dimension supplémentaire qui est la nomenclature de produit vendu mais sans me prendre la tête sur la gestion du GROUP BY (imaginez avec des requêtes où il y a 20 colonnes 😅).
WITH cte_data AS (
SELECT '2024-10-15' AS day, 'Site A' AS site, 'Ordinateur de gaming 1' AS productType, 1500 AS turnover UNION ALL
SELECT '2024-10-15' AS day, 'Site A' AS site, 'Ordinateur de gaming 2' AS productType, 1900 AS turnover UNION ALL
SELECT '2024-10-15' AS day, 'Site B' AS site, 'Ordinateur de gaming 1' AS productType, 2500 AS turnover UNION ALL
SELECT '2024-10-15' AS day, 'Site B' AS site, 'Ordinateur de gaming 1' AS productType, 1700 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site A' AS site, 'Ordinateur de gaming 1' AS productType, 1800 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site A' AS site, 'Ordinateur de gaming 1' AS productType, 2200 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site B' AS site, 'Ordinateur de gaming 1' AS productType, 2300 AS turnover UNION ALL
SELECT '2024-10-16' AS day, 'Site B' AS site, 'Ordinateur de gaming 2' AS productType, 2100 AS turnover
)
SELECT
day,
site,
productType,
SUM(turnover) AS turnoverTotal
FROM cte_data
GROUP BY ALL
;
J’ai utilisé GROUP BY ALL qui me permet de ne plus gérer les différents niveaux d’agrégations à chaque changement. Même s’il n’y a pas des changements tout le temps.
Tout va dépendre des colonnes présentes dans le SELECT.
Résultat
day | site | productType | turnoverTotal |
2024-10-15 | Site A | Ordinateur de gaming 1 | 1500 |
2024-10-15 | Site A | Ordinateur de gaming 2 | 1900 |
2024-10-15 | Site B | Ordinateur de gaming 1 | 4200 |
2024-10-16 | Site A | Ordinateur de gaming 1 | 4000 |
2024-10-16 | Site B | Ordinateur de gaming 1 | 2300 |
2024-10-16 | Site B | Ordinateur de gaming 2 | 2100 |
Merci de votre lecture !