カテゴリ:

クエリ構文

GROUP BY

同じグループごとの式で行をグループ化し、結果のグループの集計関数を計算します。GROUP BY 式は以下のいずれかになります。

  • 列名。

  • SELECT リスト内の位置を参照する番号。

  • 一般的な式です。

拡張機能:

GROUP BY CUBEGROUP BY GROUPING SETSGROUP BY ROLLUP

構文

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

条件:

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

パラメーター

column_alias

クエリブロックの SELECT リストに表示される列エイリアス。

position

SELECT リスト内の式の位置。

expr

現在のスコープ内のテーブルの式。

GROUP BY ALL

集計関数を使用しない SELECT リスト内のすべての項目をグループ化に使用するように指定します。

例については、 すべての列でグループ化する をご参照ください。

使用上の注意

  • GROUP BY 句は、名前または位置によって射影句の式を参照できます。GROUP BY 句が名前で参照している場合、各参照は次のように解決されます。

    • クエリに、一致する列名を持つデータベースオブジェクト(例: テーブルまたはビュー)が含まれている場合、参照は列名に解決されます。

    • それ以外の場合、 SELECT の射影句に一致する名前の式エイリアスが含まれていると、参照はエイリアスに解決されます。

    例については、 Precedence when a column name and an alias match をご参照ください。

  • すべての SELECT 項目が集計関数を使用する場合、 GROUP BY ALL を指定することと、 GROUP BY 句なしでステートメントを指定することは同じです。

    たとえば、次のステートメントには、集計関数を使用する SELECT 項目のみがあります。

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

    上記のステートメントは、句によって GROUP を指定しないことと同じです。

    SELECT SUM(amount)
      FROM mytable;
    
    Copy

次のセクションでは、 GROUP BY 句の使用例を示します。

各セクションの例では、 例に対するデータの設定 で設定したデータを使用していることに注意してください。

例に対するデータの設定

このセクションの例では、 sales という名前のテーブルと、 product という名前のテーブルを使用します。これらのテーブルを作成し、例に必要なデータを挿入するには、以下のステートメントを実行します。

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

1列でグループ化する

この例では、 product_id (つまり、各製品の総受取額)でグループ化された、製品ごとの総売上高を示しています。

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    |
+------------+---------------+

この例は前の例を基に構築し、製品ごとの純利益を 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 |
+------------+--------+

複数の列でグループ化する

次の例は、複数の列でグループ化する方法を示しています。

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 |
+-------+---------+---------------+

すべての列でグループ化する

次の例は、 複数の列でグループ化する で使用されている例と同じです。

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 |
+-------+---------+---------------+

Precedence when a column name and an alias match

It is possible (but usually not recommended) to create a query that contains an alias that matches a column name:

SELECT x, some_expression AS x
  FROM ...
Copy

If a clause contains a name that matches both a column name and an alias, then the clause uses the column name. The following example demonstrates this behavior using a GROUP BY clause:

テーブルを作成して行を挿入します。

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

The following query returns the sum of the salaries of the employees who are active and the sum of the salaries of the employees who are on leave:

SELECT SUM(salary), ANY_VALUE(employment_state)
  FROM employees
  GROUP BY employment_state;
Copy
+-------------+-----------------------------+
| SUM(SALARY) | ANY_VALUE(EMPLOYMENT_STATE) |
|-------------+-----------------------------|
|      140000 | Active                      |
|       70000 | On leave                    |
+-------------+-----------------------------+

The next query uses the alias state, which matches the name of a column of the table in the query. When state is used in the GROUP BY clause, Snowflake interprets it as a reference to the column name, not the alias. This query therefore returns the sum of the salaries of the employees in the state of California and the sum of the salaries of the employees in the state of Oregon, yet displays employment_state information (that is, Active) rather than the names of states or provinces.

SELECT SUM(salary), ANY_VALUE(employment_state) AS state
  FROM employees
  GROUP BY state;
Copy
+-------------+--------+
| SUM(SALARY) | STATE  |
|-------------+--------|
|      130000 | Active |
|       80000 | Active |
+-------------+--------+