14th May 2024 19 minutes de lecture Fonctions GROUP BY et Aggregate : Vue d'ensemble Tihomir Babic Fonctions d’agrégation group by Table des matières Syntaxe de base de GROUP BY avec agrégats Fonctions d'agrégation SQL Utilisation de GROUP BY avec les fonctions agrégées de SQL Exemple 1 : COUNT() avec GROUP BY Exemple 2 : SUM() avec GROUP BY Exemple 3 : AVG() avec GROUP BY Exemple 4 : MIN() et MAX() avec GROUP BY Techniques avancées de GROUP BY Filtrage des résultats agrégés avec HAVING Regroupement par colonnes multiples Exemple Deux fonctions d'agrégation en une seule requête Une requête, deux fonctions agrégées : L'approche simple Exemple Une requête, deux fonctions agrégées : L'approche avancée Exemple GROUP BY avec des agrégats conditionnels Exemple Extensions de GROUP BY : ROLLUP, CUBE, ENSEMBLES DE REGROUPEMENT Exemple Erreurs courantes lors de l'utilisation de GROUP BY Confusion entre ORDER BY et GROUP BY Confusion entre WHERE et HAVING Exemple Énumérer les colonnes non agrégées dans SELECT mais pas dans WHERE Exemple Autres erreurs Autres ressources SQL GROUP BY Les fonctions GROUP BY et aggregate de SQL sont essentielles pour l'agrégation des données, l'analyse des données et la création de rapports. Explorons-les ensemble ! En SQL, les fonctions GROUP BY et d'agrégation sont l'une des fonctionnalités les plus populaires du langage. L'agrégation de données est essentielle pour l'analyse des données et la création de rapports ; pour donner un sens à toutes les données d'un ensemble de données, il est souvent nécessaire de les agréger. Mais qu'est-ce que l'agrégation de données ? En termes simples, il s'agit de regrouper des données sur la base de valeurs communes et d'effectuer un calcul pour chaque groupe de données. Par exemple, vous pouvez regrouper une liste de chiens en fonction de leur race, puis utiliser un calcul pour déterminer la taille moyenne de chaque race. Cette tâche est rendue possible par la clause GROUP BY et la fonction d'agrégation AVG(). Si vous avez besoin de rafraîchir vos connaissances sur GROUP BY, notre cours est idéal. SQL pour les débutants cours est idéal. Il comporte 129 exercices interactifs que vous pouvez terminer en 10 heures environ. Il couvre des sujets tels que le filtrage des données, l'utilisation d'opérateurs logiques, la jointure et l'utilisation d'opérateurs d'ensemble. Syntaxe de base de GROUP BY avec agrégats GROUP BY Le groupe BY est une clause de SQL qui permet de regrouper les données ayant les mêmes valeurs. Le regroupement se fait par colonne(s), toutes les lignes ayant la même valeur dans cette colonne appartenant à un groupe. Vous pouvez ensuite effectuer des calculs récapitulatifs - tels que le comptage, la somme ou la moyenne des valeurs - pour chaque groupe. Par exemple, vous pouvez utiliser GROUP BY pour calculer le nombre d'employés dans un service, le salaire total ou le salaire moyen par service, etc. La syntaxe de GROUP BY avec une fonction d'agrégation est la suivante : SELECT column1, column2, ..., aggregate_function(column_name) FROM table_name WHERE filtering_condition GROUP BY column1, column2, … HAVING filtering_condition; La fonction d'agrégation est écrite dans l'instruction SELECT, et le résultat de la fonction est affiché dans une colonne supplémentaire. La clause GROUP BY contient les colonnes par lesquelles vous souhaitez que votre résultat soit groupé. Cette clause est souvent utilisée avec les clauses WHERE et HAVING pour le filtrage. Dans la syntaxe, WHERE vient avant GROUP BY, tandis que HAVING vient après. (Je reviendrai sur ces deux clauses plus tard.) Par ailleurs, vos données contiendront parfois NULLs, et vous serez donc intéressé par la façon dont GROUP BY traite les NULL. Un exemple de GROUP BY en action est présenté dans le GIF suivant. Cet exemple de base regroupe les données par réalisateur et indique le nombre de films réalisés par chacun d'entre eux. Fonctions d'agrégation SQL Les fonctions agrégées de SQL sont utilisées lorsque vous souhaitez effectuer des calculs sur des données et renvoyer une valeur unique. Les fonctions agrégées les plus courantes de SQL sont les suivantes : COUNT() - Compte les lignes de la colonne indiquée. SUM() - Renvoie la somme de toutes les valeurs. AVG () - Calcule la moyenne d'un groupe de valeurs. MIN() - Renvoie le minimum (la plus petite valeur) des valeurs données. MAX() - Renvoie le maximum (la valeur la plus élevée) des valeurs données. Consultez nos guides sur l'utilisation de ces fonctions pour calculer des agrégats pour l'ensemble du tableau : Comment compter le nombre de lignes dans un tableau en SQL Comment compter les valeurs distinctes en SQL Comment additionner les valeurs d'une colonne en SQL ? Comment trouver la moyenne d'une colonne numérique en SQL ? Comment trouver la valeur maximale d'une colonne en SQL ? Comment trouver la valeur minimale d'une colonne en SQL ? Il est important de noter que la fonction COUNT() a plusieurs variantes d'utilisation : COUNT(*) compte toutes les lignes d'un ensemble de résultats, y compris les valeurs NULL et les doublons. COUNT(expression) compte les valeurs non NULL dans un ensemble de résultats. COUNT(DISTINCT) compte les valeurs distinctes et ignore les doublons. Pour plus de détails, consultez notre guide Quelle est la différence entre COUNT(*), COUNT(1), COUNT(column) et COUNT(DISTINCT) ? Utilisation de GROUP BY avec les fonctions agrégées de SQL J'utiliserai le tableau albums pour montrer comment les fonctions agrégées et GROUP BY fonctionnent ensemble. Le script de création de la table se trouve ici. Cette table contient des données sur les albums musicaux. Voici un aperçu de la situation : idartistalbumrelease_yearlengthlabel 1Grant GreenThe Latin Bit19630:38:56Blue Note Records 2AC/DCHigh Voltage19760:44:23Atlantic Records 3Brother Jack McDuffTo Seek a New Home19700:33:12Blue Note Records 4Grant GreenGreen Is Beautiful19700:37:33Blue Note Records 5Wayne ShorterMoto Grosso Feio19740:42:22Blue Note Records Exemple 1 : COUNT() avec GROUP BY Voici un exemple de code qui compte le nombre d'albums par étiquette : SELECT label, COUNT(*) AS number_of_albums FROM albums GROUP BY label; Je sélectionne l'étiquette et j'utilise COUNT(*) pour trouver le nombre d'albums. L'astérisque (*) est un raccourci pour compter toutes les lignes. Lorsque je regroupe les résultats par étiquette, COUNT() affiche le nombre d'albums par étiquette. Voici le résultat : labelnumber_of_albums Atlantic Records13 Blue Note Records12 Stax Records14 Pour en savoir plus : Guide détaillé de la fonction SQL COUNT() La fonction SQL Count expliquée avec 7 exemples Comment compter le nombre de lignes dans une table en SQL. Quelle est la différence entre COUNT(*), COUNT(1), COUNT(column), et COUNT(DISTINCT) ? Comment compter des valeurs distinctes en SQL. Exemple 2 : SUM() avec GROUP BY Le code suivant additionne les longueurs des albums pour afficher le total de la musique disponible par artiste : SELECT artist, SUM(length) AS total_music_available FROM albums GROUP BY artist; La fonction SUM() est appliquée à la colonne length et le résultat est ensuite regroupé par artiste. Voici le résultat du code : artisttotal_music_available Isaac Hayes6:30:02 Otis Redding1:34:09 Brother Jack McDuff1:58:11 Aretha Franklin1:47:07 Grant Green3:10:11 John Prine1:21:57 Led Zeppelin3:32:07 Wayne Shorter2:38:02 Albert King3:08:28 AC/DC2:05:23 Pour en savoir plus : La fonction SQL SUM() expliquée avec 5 exemples pratiques Comment additionner les valeurs d'une colonne en SQL Exemple 3 : AVG() avec GROUP BY Ce code calcule la durée moyenne des albums de chaque artiste : SELECT artist, AVG(length) AS average_album_length FROM albums GROUP BY artist; Pour obtenir le résultat souhaité, vous devez utiliser AVG() sur la colonne length et grouper le résultat par artist. Voici à quoi ressemble le résultat : artistaverage_album_length Isaac Hayes1:05:00 Otis Redding0:31:23 Brother Jack McDuff0:39:24 Aretha Franklin0:35:42 Grant Green0:38:02 John Prine0:40:59 Led Zeppelin0:42:25 Wayne Shorter0:39:31 Albert King0:37:42 AC/DC0:41:48 Pour en savoir plus : La fonction SQL AVG() expliquée avec des exemples Comment trouver la moyenne d'une colonne numérique en SQL Exemple 4 : MIN() et MAX() avec GROUP BY Trouvons la longueur d'album la plus courte et la plus longue pour chaque année : SELECT release_year, MIN(length) AS minimum_album_length, MAX(length) AS maximum_album_length FROM albums GROUP BY release_year ORDER BY release_year; Comme dans les exemples précédents, les fonctions d'agrégation sont utilisées sur la colonne length; MIN() pour l'album le plus court et MAX() pour l'album le plus long. Les résultats sont regroupés par année de sortie. J'ai également ajouté la clause ORDER BY pour trier les résultats de l'année la plus ancienne à l'année la plus récente afin de les rendre plus lisibles. Voici le résultat du code : release_yearminimum_album_lengthmaximum_album_length 19620:34:490:34:49 19630:38:560:38:56 19640:30:170:30:17 19650:32:220:42:45 19670:32:510:41:08 19680:29:300:29:30 19690:31:300:46:00 19700:33:120:43:04 19710:42:371:33:38 19720:37:500:44:46 19730:40:571:43:10 19740:42:220:46:00 19760:39:590:44:23 19770:41:010:41:01 Pour en savoir plus : Les fonctions MIN et MAX de SQL expliquées en 6 exemples Comment trouver la valeur maximale d'une colonne numérique en SQL Comment trouver la valeur minimale d'une colonne en SQL Techniques avancées de GROUP BY La section précédente traitait des bases de l'utilisation des fonctions agrégées SQL et de GROUP BY. Ces bases étant posées, nous pouvons maintenant explorer quelques techniques avancées de GROUP BY. Filtrage des résultats agrégés avec HAVING Pour filtrer les résultats agrégés, vous devez utiliser la clause HAVING. Sa syntaxe est illustrée ci-dessous : SELECT column1, column2, ..., aggregate_function(column_name) FROM table_name GROUP BY column1, column2, … HAVING filtering_condition; HAVING compare les valeurs agrégées à la condition de filtrage et renvoie uniquement les valeurs qui satisfont à cette condition. Pour en savoir plus, consultez notre article sur la clause HAVING. Laissez-moi vous montrer un exemple. Le code suivant calcule la durée moyenne des albums par artiste, mais il n'affiche que ceux dont la durée moyenne est inférieure à 40 minutes. SELECT artist, AVG(length) AS average_album_length FROM albums GROUP BY artist HAVING AVG(length) < '00:40:00'; J'ai utilisé la fonction AVG() de la même manière que précédemment. La clause HAVING est nouvelle. Pour filtrer les données de la manière voulue, j'ai écrit dans HAVING le même calcul de moyenne que celui qui apparaît dans SELECT. Ensuite, j'utilise l'opérateur de comparaison 'less than'(<) pour comparer chaque résultat groupé à une valeur (dans ce cas, 40 minutes). Cette valeur est placée entre guillemets simples (''). La valeur entre guillemets doit être écrite au format HH:MM:SS (heures:minutes:secondes) parce que les valeurs de la colonne length sont du type de données INTERVAL. Voici le résultat : artistaverage_album_length Otis Redding0:31:23 Brother Jack McDuff0:39:24 Aretha Franklin0:35:42 Grant Green0:38:02 Wayne Shorter0:39:31 Albert King0:37:42 Le principe est le même quelle que soit la fonction d'agrégation que vous utilisez, mais voici les livres de recettes pour vous aider avec d'autres fonctions : Comment filtrer des enregistrements avec la fonction agrégative COUNT Comment filtrer les enregistrements avec la fonction agrégative SUM Comment filtrer les enregistrements avec la fonction d'agrégation AVG Regroupement par colonnes multiples Jusqu'à présent, j'ai regroupé les données en fonction d'une seule colonne. Cependant, il est également possible de regrouper les données en fonction de deux colonnes ou plus. Ce n'est pas compliqué : Il suffit d'énumérer toutes les colonnes de regroupement dans GROUP BY et de les séparer par des virgules. Ce faisant, vous effectuez un regroupement en fonction des valeurs des colonnes, mais aussi en fonction de la combinaison des valeurs de toutes les colonnes de regroupement. Si vous avez la valeur A dans la colonne_1 et la valeur B dans la colonne_2, il s'agit d'un groupe. S'il y a, par exemple, des valeurs A dans la colonne_1 et des valeurs C dans la colonne_2, cela formera un autre groupe - bien que les valeurs de la colonne_1 soient les mêmes que dans l'exemple précédent. Exemple Le code ci-dessous indique le nombre d'albums de l'artiste et l'année de sortie : SELECT artist, release_year, COUNT(*) AS number_of_albums FROM albums GROUP BY artist, release_year ORDER BY artist, release_year; J'utilise COUNT(*) pour trouver le nombre d'albums. Les résultats sont regroupés par artiste et année de sortie. Comme vous pouvez le voir, ce sont exactement les colonnes de GROUP BY et elles sont séparées par une virgule. Pour rendre le résultat plus lisible, j'ai trié les données par artiste dans l'ordre alphabétique et de l'année de sortie la plus ancienne à la plus récente. Voici l'aperçu de la sortie : artistrelease_yearnumber_of_albums AC/DC19762 AC/DC19771 Albert King19621 Albert King19671 Albert King19691 Albert King19721 Albert King19741 Aretha Franklin19671 Aretha Franklin19681 Aretha Franklin19721 Brother Jack McDuff19692 Brother Jack McDuff19701 Deux fonctions d'agrégation en une seule requête Il est également possible d'écrire une requête comportant deux fonctions d'agrégation. Non, ce n'est pas ce que vous pensez : vous n'écrivez pas une fonction agrégée à l'intérieur d'une autre. Ce n'est pas possible en SQL. Deux fonctions agrégées dans une même requête, cela peut vouloir dire deux choses : Approche simple : Utilisation de deux fonctions agrégées dans deux colonnes du même SELECT. Approche avancée : Utilisation du résultat d'une fonction agrégée dans une autre fonction agrégée. Une requête, deux fonctions agrégées : L'approche simple L'approche simple consiste à utiliser deux fonctions agrégées dans deux colonnes agrégées différentes sur le site SELECT. Il peut s'agir de la même fonction appliquée à des colonnes différentes, de fonctions différentes utilisées sur la même colonne ou de fonctions différentes utilisées sur des colonnes différentes. Cela n'a pas vraiment d'importance ; le fait est que vous avez deux agrégations dans une seule requête. Ces agrégations ne "communiquent" pas, c'est-à-dire qu'elles ne dépendent pas l'une de l'autre de quelque manière que ce soit. Exemple Dans l'exemple, j'utiliserai le tableau package_deliveries avec le script lié ici. Le tableau contient des informations sur le nombre de colis livrés quotidiennement dans plusieurs villes. Voici les six premières lignes du tableau : iddate_of_deliverynumber_of_packagescity_of_deliverycountry_of_delivery 12024-03-0149KrakowPoland 22024-03-01528WarsawPoland 32024-03-01158GdanskPoland 42024-03-0128RijekaCroatia 52024-03-0197SplitCroatia 62024-03-0164ZagrebCroatia Le code ci-dessous calcule le nombre total et le nombre moyen de colis par ville. SELECT city_of_delivery, SUM(number_of_packages) AS total_number_of_packages, AVG(number_of_packages) AS average_number_of_packages FROM package_deliveries GROUP BY city_of_delivery; Vous pouvez voir que la requête comporte deux agrégats : un avec SUM() et un avec AVG(). Le nombre de fonctions d'agrégat que vous écrivez dans la requête n'a pas vraiment d'importance. La seule chose importante est que chaque agrégat soit traité comme une ligne de code ou une colonne de sortie distincte. Voici le résultat : city_of_deliverytotal_number_of_packagesaverage_number_of_packages Split531177.00 Izmir5,9361,978.67 Ankara9,1393,046.33 Gdansk712237.33 Rijeka627209.00 Zagreb930310.00 Istanbul13,8574,619.00 Krakow673224.33 Warsaw2,358786.00 Une requête, deux fonctions agrégées : L'approche avancée Dans la version avancée, les agrégats "communiquent", c'est-à-dire que vous devez d'abord trouver une valeur agrégée, puis l'utiliser pour calculer une autre valeur agrégée. Généralement, cela se fait par le biais de sous-requêtes ou d'expressions de tableau communes (CTE). Je vous montrerai l'utilisation des sous-requêtes dans l'exemple ci-dessous. Notre guide sur la combinaison de deux fonctions agrégées dans GROUP BY couvre les deux approches. Exemple Le code suivant renvoie le nombre quotidien moyen de colis livrés dans chaque pays : SELECT country_of_delivery, AVG(pd.daily_number_of_packages) AS average_daily_number_of_packages FROM (SELECT date_of_delivery, country_of_delivery, SUM(number_of_packages) AS daily_number_of_packages FROM package_deliveries GROUP BY date_of_delivery, country_of_delivery) AS pd GROUP BY country_of_delivery; Je dois d'abord trouver le nombre de colis livrés quotidiennement dans chaque pays, ce qui constitue la première agrégation. La deuxième agrégation utilise ce résultat et calcule la moyenne quotidienne par pays. La première agrégation est écrite dans la sous-requête. Elle utilise la fonction SUM() et répertorie les colonnes date_of_delivery et country_of_delivery dans SELECT. Le résultat est groupé par les mêmes colonnes. Je peux maintenant écrire la requête principale, en référençant dans AVG() la colonne daily_number_of_packages de la sous-requête. Je regroupe les résultats par pays et j'obtiens le nombre quotidien moyen de colis livrés pour chaque pays. country_of_deliveryaverage_daily_number_of_packages Turkey9,644.00 Croatia696.00 Poland1,247.67 GROUP BY avec des agrégats conditionnels L'instruction CASE ou CASE WHEN étiquette les données en fonction de leurs valeurs. Cette instruction peut également être utilisée avec GROUP BY. Le regroupement des données par agrégats conditionnels implique l'utilisation de CASE WHEN avec GROUP BY. Cependant - et c'est important - le CASE WHEN que vous écrivez dans SELECT doit également apparaître dans GROUP BY. Exemple En utilisant le tableau de l'exemple précédent, je peux écrire un code qui classe les pays en pays de l'UE et en pays hors UE et qui indique le nombre total de colis livrés pour chaque catégorie : SELECT CASE WHEN country_of_delivery = 'Turkey' THEN 'Non-EU' ELSE 'EU' END, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY CASE WHEN country_of_delivery = 'Turkey' THEN 'Non-EU' ELSE 'EU' END; L'énoncé CASE indique que la Turquie doit être classée dans la catégorie des pays non membres de l'UE. Cette condition est énoncée sur le site WHEN. La catégorie pour tous les autres pays est l'UE, ce qui est écrit dans ELSE. La déclaration CASE commence par CASE (d'où son nom) et se termine par le mot-clé END. J'utilise la fonction SUM() pour calculer le nombre total de paquets. Pour afficher cette valeur par catégorie, j'ai simplement copié l'intégralité de la déclaration CASE WHEN dans GROUP BY. Voici le résultat : casetotal_number_of_packages Non-EU28,932 EU5,831 Si vous avez besoin de plus d'exemples pour bien comprendre, lisez l'un de nos guides : Comment utiliser CASE WHEN avec SUM() en SQL Comment utiliser CASE WHEN dans GROUP BY Extensions de GROUP BY : ROLLUP, CUBE, ENSEMBLES DE REGROUPEMENT Les trois extensions SQL GROUP BY sont les suivantes ROLLUP - Crée une ligne de résumé pour les groupes énumérés dans GROUP BY. CUBE - Crée des sous-totaux pour toutes les combinaisons des groupes figurant dans GROUP BY. GROUPING SETS - Agrégation des résultats à plusieurs niveaux. Dans l'exemple, je vous montrerai comment fonctionnent les GROUPING SETS. Pour en savoir plus sur le fonctionnement des deux autres extensions, consultez notre guide sur les extensions GROUP BY. Exemple Le code suivant renvoie le nombre de colis livrés par pays et par date : SELECT country_of_delivery, date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY GROUPING SETS(country_of_delivery, date_of_delivery) ORDER BY country_of_delivery, date_of_delivery; Je commence par utiliser SUM() pour calculer le nombre de colis. Dans GROUP BY, j'écris GROUPING SETS avec tous les niveaux d'agrégation entre parenthèses. Le résultat montre le nombre de colis livrés par pays et par date de livraison : country_of_deliverydate_of_deliverytotal_number_of_packages CroatiaNULL2,088 PolandNULL3,743 TurkeyNULL28,932 NULL2024-03-012,730 NULL2024-03-0211,208 NULL2024-03-0320,825 Il peut être utile de considérer les ensembles de regroupement comme deux requêtes distinctes. La première requête regroupe par pays ... SELECT country_of_delivery, NULL AS date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery ORDER BY country_of_delivery; ... et renvoie les trois premières lignes de la sortie précédente : country_of_deliverydate_of_deliverytotal_number_of_packages CroatiaNULL2,088 PolandNULL3,743 TurkeyNULL28,932 La seconde requête regroupe les données par date de livraison ... SELECT NULL AS country_of_delivery, date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY date_of_delivery ORDER BY date_of_delivery; ... et renvoie les trois autres lignes du résultat original : country_of_deliverydate_of_deliverytotal_number_of_packages NULL2024-03-012,730 NULL2024-03-0211,208 NULL2024-03-0320,825 En d'autres termes, si vous fusionnez ces deux requêtes de regroupement distinctes à l'aide de UNION... SELECT country_of_delivery, NULL AS date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery UNION SELECT NULL AS country_of_delivery, date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY date_of_delivery ORDER BY country_of_delivery, date_of_delivery; ... vous obtenez exactement le même résultat qu'avec GROUPING SETS. country_of_deliverydate_of_deliverytotal_number_of_packages CroatiaNULL2,088 PolandNULL3,743 TurkeyNULL28,932 NULL2024-03-012,730 NULL2024-03-0211,208 NULL2024-03-0320,825 Erreurs courantes lors de l'utilisation de GROUP BY Confusion entre ORDER BY et GROUP BY Il s'agit souvent de ne pas savoir ce que fait GROUP BY. Permettez-moi de vous donner un exemple. Supposons que vous souhaitiez trouver le nombre total de colis par pays de livraison. Si vous ne connaissez pas GROUP BY, vous pouvez écrire une solution naïve en utilisant ORDER BY. SELECT date_of_delivery, city_of_delivery, country_of_delivery FROM package_deliveries ORDER BY country_of_delivery; Maintenant que vous avez trié les données par pays, comme le montre la capture d'écran ci-dessous, vous décidez d'additionner manuellement les valeurs pour obtenir le résultat par pays. date_of_deliverycity_of_deliverycountry_of_delivery 2024-03-01RijekaCroatia 2024-03-01SplitCroatia 2024-03-01ZagrebCroatia 2024-03-02RijekaCroatia 2024-03-02SplitCroatia 2024-03-02ZagrebCroatia 2024-03-03ZagrebCroatia 2024-03-03SplitCroatia 2024-03-03RijekaCroatia 2024-03-01KrakowPoland 2024-03-01WarsawPoland Mais pourquoi feriez-vous manuellement quelque chose que GROUP BY fait automatiquement ? Au lieu de classer les données par pays, vous devriez les regrouper par pays et utiliser SUM() pour additionner les données : SELECT country_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery ORDER BY country_of_delivery; Vous obtiendrez immédiatement le résultat dont vous avez besoin : country_of_deliverytotal_number_of_packages Croatia2,088 Poland3,743 Turkey28,932 Pour en savoir plus sur les différences entre GROUP BY et ORDER BY et sur la manière d'utiliser GROUP BY et ORDER BY ensemble. Confusion entre WHERE et HAVING Une autre erreur fréquente consiste à essayer de filtrer des valeurs agrégées à l'aide de WHERE. Ce n'est pas possible - WHERE est utilisé pour filtrer les lignes individuelles avant l' agrégation. En revanche, HAVING sert à filtrer des groupes de lignes après l' agrégation. Exemple Si vous souhaitez obtenir le nombre moyen de colis livrés quotidiennement par ville et n'afficher que les villes ayant livré plus de 500 colis, vous pouvez décider d'écrire cette requête : SELECT city_of_delivery, AVG(number_of_packages) AS average_number_of_packages FROM package_deliveries WHERE AVG(number_of_packages) > 500 GROUP BY city_of_delivery; Elle renverra une erreur car WHERE n'accepte pas de fonction d'agrégation en tant qu'argument. (Cela ne signifie pas que vous ne pouvez jamais utiliser WHERE avec GROUP BY; vous le pouvez, mais pas pour filtrer des groupes). Dans ce cas, vous devez utiliser HAVING: SELECT city_of_delivery, AVG(number_of_packages) AS average_number_of_packages FROM package_deliveries GROUP BY city_of_delivery HAVING AVG(number_of_packages) > 500; Il s'agit de la même requête avec AVG() et GROUP BY. La seule différence est HAVING, où vous comparez le calcul de AVG() avec 500. Le résultat n'affiche que les villes dont la moyenne quotidienne est supérieure à 500. city_of_deliveryaverage_number_of_packages Izmir1,978.67 Ankara3,046.33 Istanbul4,619.00 Warsaw786.00 Pour en savoir plus, consultez l'article HAVING vs WHERE. Énumérer les colonnes non agrégées dans SELECT mais pas dans WHERE La règle simple dont vous devez vous souvenir est que toute colonne non agrégée que vous écrivez dans SELECT doit également être incluse dans GROUP BY. Si vous ne le faites pas, la base de données ne saura pas quelle valeur afficher si plusieurs valeurs différentes se trouvent dans le même groupe. Exemple Par exemple, vous écrivez une requête censée calculer le nombre total de paquets par pays et par ville. SELECT country_of_delivery, city_of_delivery, SUM(number_of_packages) total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery; Bien sûr, vous avez le pays et la ville dans SELECT, mais vous avez oublié de mettre la ville dans GROUP BY. Cette requête ne s'exécutera pas. Elle renvoie une erreur. Bien que les messages soient formulés différemment dans PostgreSQL, Oracle et d'autres bases de données, le message est le même : la colonne city_of_delivery doit apparaître dans GROUP BY. Même si elle s'exécutait, la base de données serait confuse. Elle penserait à peu près ceci : "Vous voulez afficher les villes, mais vous ne voulez pas grouper par ville ? Comment suis-je censé savoir quelle ville afficher dans le résultat alors que chaque pays en compte trois ? S'il vous plaît, mettez les villes dans GROUP BY pour que je puisse afficher chaque ville comme un groupe séparé." Vous l'aidez donc en incluant la ville de livraison dans GROUP BY: SELECT country_of_delivery, city_of_delivery, SUM(number_of_packages) total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery, city_of_delivery; Oui, il s'agit d'un regroupement sur deux colonnes et vous avez déjà appris à le faire. Voici le résultat de la requête : country_of_deliverycity_of_deliverytotal_number_of_packages CroatiaZagreb930 CroatiaRijeka627 CroatiaSplit531 TurkeyIstanbul13,857 PolandWarsaw2,358 PolandKrakow673 TurkeyAnkara9,139 PolandGdansk712 TurkeyIzmir5,936 Autres erreurs Il y a aussi d'autres erreurs, comme l'oubli de GROUP BY avec des fonctions agrégées ou le fait de ne pas grouper par une clé unique. Ces erreurs et bien d'autres sont abordées dans cet article sur les erreurs courantes de GROUP BY. Autres ressources SQL GROUP BY Après avoir lu cet aperçu de la clause SQL GROUP BY, vous devriez avoir une idée de ses utilisations et de ses défis. Mais si vous voulez maîtriser GROUP BY, vous devrez entrer dans les détails. La meilleure façon de le faire est de consulter certains de nos cours et livres de cuisine. Voici quelques-unes de mes suggestions pour poursuivre votre apprentissage : Création de rapports basiques en SQL - Ce cours de niveau intermédiaire se concentre sur les nuances de l'utilisation de GROUP BY - le regroupement par colonnes multiples, l'utilisation de HAVING, la combinaison de GROUP BY avec CASE WHEN, la différence entre COUNT(*) et COUNT(id), etc. Les extensions GROUP BY en SQL - Ce cours couvre CUBE, ROLLUP, et GROUPING SETS. La pratique du SQL - Les cours de cette filière comportent des sections consacrées à différents sujets SQL, y compris de nombreux exercices pratiques sur GROUP BY. N'oubliez pas non plus nos articles présentant des exemples GROUP BY. Deux de mes préférés sont La pratique du SQL: 10 exercices pratiques GROUP BY avec solutions détaillées et Top 9 SQL GROUP BY Interview Questions. En outre, il existe une antisèche SQL pour l'analyse de données, qui comporte une section consacrée à GROUP BY. Bon apprentissage ! Tags: Fonctions d’agrégation group by