Catégories :

Syntaxe de requête

GROUP BY

Regroupe les lignes avec les mêmes expressions group-by-item et calcule les fonctions d’agrégation pour le groupe résultant. Une expression de GROUP BY peut être :

  • Nom de colonne.

  • Un numéro annonçant une position dans la liste SELECT.

  • Une expression générale.

Extensions :

GROUP BY CUBE, GROUP BY GROUPING SETS, GROUP BY ROLLUP

Syntaxe

SELECT ...
  FROM ...
  [ ... ]
  GROUP BY groupItem [ , groupItem [ , ... ] ]
  [ ... ]
Copy
SELECT ...
  FROM ...
  [ ... ]
  GROUP BY ALL
  [ ... ]
Copy

Où :

GROUP BY groupItem [ , groupItem [ , ... ] ]

Spécifie les alias de colonne, les positions ou les expressions à utiliser pour le regroupement. Pour chaque groupItem, utilisez la syntaxe suivante :

groupItem ::= { <column_alias> | <position> | <expr> }
Copy

Où :

  • column_alias spécifie l’alias de colonne figurant dans la liste SELECT du bloc de requête.

  • position spécifie la position d’une expression dans la liste SELECT.

  • expr spécifie toute expression sur les tables du périmètre actuel.

GROUP BY ALL

Spécifie que tous les éléments de la liste SELECT qui n’utilisent pas de fonctions d’agrégation doivent être utilisés pour le regroupement.

Pour des exemples, reportez-vous à Grouper par toute les colonnes.

Notes sur l’utilisation

  • Une clause GROUP BY peut faire référence à des expressions dans la clause de projection par nom ou par position. Si la clause GROUP BY fait référence à un nom, alors chaque référence est résolue comme suit :

    • Si la requête contient un objet de base de données (par exemple, une table ou une vue) avec un nom de colonne correspondant, la référence est résolue au nom de la colonne.

    • Sinon, si la clause de projection de SELECT contient un alias d’expression avec un nom correspondant, alors la référence est résolue vers l’alias.

    Pour un exemple, voir Démontrer la priorité lorsqu’un nom de colonne et un alias correspondent.

  • Si tous les éléments SELECT utilisent des fonctions agrégées, spécifier GROUP BY ALL équivaut à spécifier l’instruction sans la clause GROUP BY.

    Par exemple, l’instruction suivante ne comporte que des éléments SELECT qui utilisent des fonctions d’agrégation :

    SELECT SUM(amount)
      FROM mytable
      GROUP BY ALL;
    
    Copy

    L’instruction ci-dessus équivaut à ne pas spécifier la clause GROUP by :

    SELECT SUM(amount)
      FROM mytable;
    
    Copy

Exemples

Les sections suivantes fournissent des exemples d’utilisation de la clause GROUPBY :

Notez que les exemples de chaque section utilisent les données que vous avez configurées dans Configuration des données pour les exemples.

Configuration des données pour les exemples

Les exemples de cette section utilisent une table nommée sales et une table nommée product. Pour créer ces tables et insérer les données nécessaires à l’exemple, exécutez les instructions suivantes :

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');

CREATE TABLE products (
  product_ID INTEGER,
  wholesale_price REAL);
INSERT INTO products (product_ID, wholesale_price) VALUES (1, 1.00);
INSERT INTO products (product_ID, wholesale_price) VALUES (2, 2.00);
Copy

Grouper par une colonne

Cet exemple montre les recettes brutes par produit, regroupées par product_id (c’est-à-dire le montant total reçu pour chaque produit) :

SELECT product_ID, SUM(retail_price * quantity) AS gross_revenue
  FROM sales
  GROUP BY product_ID;
Copy
+------------+---------------+
| PRODUCT_ID | GROSS_REVENUE |
+============+===============+
|          1 |          6    |
+------------+---------------+
|          2 |        620    |
+------------+---------------+

L’exemple suivant s’appuie sur l’exemple précédent et présente le bénéfice net par produit, regroupé par product_id :

SELECT p.product_ID, 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 p.product_ID;
Copy
+------------+--------+
| PRODUCT_ID | PROFIT |
+============+========+
|          1 |      3 |
+------------+--------+
|          2 |    372 |
+------------+--------+

Vous pouvez grouper par plusieurs colonnes :

L’exemple suivant montre comment effectuer un groupe sur plusieurs colonnes :

SELECT state, city, SUM(retail_price * quantity) AS gross_revenue
  FROM sales
  GROUP BY state, city;
Copy
+-------+---------+---------------+
| STATE |   CITY  | GROSS REVENUE |
+=======+=========+===============+
|   CA  | SF      |            22 |
+-------+---------+---------------+
|   CA  | SJ      |            44 |
+-------+---------+---------------+
|   FL  | Miami   |            80 |
+-------+---------+---------------+
|   FL  | Orlando |           160 |
+-------+---------+---------------+
|   PR  | SJ      |           320 |
+-------+---------+---------------+

Grouper par toute les colonnes

L’exemple suivant est équivalent à l’exemple utilisé dans Vous pouvez grouper par plusieurs colonnes :.

SELECT state, city, SUM(retail_price * quantity) AS gross_revenue
  FROM sales
  GROUP BY ALL;
Copy
+-------+---------+---------------+
| STATE |   CITY  | GROSS REVENUE |
+=======+=========+===============+
|   CA  | SF      |            22 |
+-------+---------+---------------+
|   CA  | SJ      |            44 |
+-------+---------+---------------+
|   FL  | Miami   |            80 |
+-------+---------+---------------+
|   FL  | Orlando |           160 |
+-------+---------+---------------+
|   PR  | SJ      |           320 |
+-------+---------+---------------+

Démontrer la priorité lorsqu’un nom de colonne et un alias correspondent

Il est possible (mais c’est généralement une mauvaise idée) de créer une requête qui contient un alias correspondant à un nom de colonne :

SELECT x, some_expression AS x
  FROM ...
Copy

Si une clause GROUP BY contient un nom qui correspond à la fois à un nom de colonne et à un alias, alors la clause GROUP BY utilise le nom de la colonne. Voici une démonstration dans l’exemple ci-dessous.

Créer une table et insérer des lignes :

Create table employees (salary float, state varchar, employment_state varchar);
insert into employees (salary, state, employment_state) values
    (60000, 'California', 'Active'),
    (70000, 'California', 'On leave'),
    (80000, 'Oregon', 'Active');
Copy

La requête ci-dessous renvoie la somme des salaires des employés qui sont actifs et la somme des salaires des employés qui sont en congé.

select sum(salary), ANY_VALUE(employment_state)
    from employees
    group by employment_state;
+-------------+-----------------------------+
| SUM(SALARY) | ANY_VALUE(EMPLOYMENT_STATE) |
|-------------+-----------------------------|
|      140000 | Active                      |
|       70000 | On leave                    |
+-------------+-----------------------------+
Copy

La requête ci-dessous utilise l’alias state, qui correspond au nom d’une colonne d’une table dans la requête. Lorsque state est utilisé dans GROUP BY, Snowflake l’interprète comme une référence au nom de la colonne, et non à l’alias. Cette requête renvoie donc la somme des salaires des employés de l’État de Californie et la somme des salaires des employés de l’État de l’Oregon, tout en affichant les informations employment_state (par ex. « Active ») plutôt que des noms d’États ou de provinces.

select sum(salary), ANY_VALUE(employment_state) as state
    from employees
    group by state;
+-------------+--------+
| SUM(SALARY) | STATE  |
|-------------+--------|
|      130000 | Active |
|       80000 | Active |
+-------------+--------+
Copy