カテゴリ:

クエリ構文

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

条件:

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

グループ化に使用する列のエイリアス、位置、または式を指定します。各 groupItem に、以下の構文を使用します。

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

条件:

  • column_alias は、クエリブロックの SELECT リストに表示される列エイリアスを指定します。

  • SELECT は、 position リスト内の式の位置を指定します。

  • expr は、現在のスコープ内のテーブルにある任意の式を指定します。

GROUP BY ALL

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

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

使用上の注意

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

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

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

    例については、 列名とエイリアスが一致する場合の優先順位の実証 をご参照ください。

  • すべての 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 |
+-------+---------+---------------+

列名とエイリアスが一致する場合の優先順位の実証

列名に一致するエイリアスを含むクエリを作成することは可能です(ただし、通常は悪い考えです)。

SELECT x, some_expression AS x
  FROM ...
Copy

GROUP BY 句に、列名とエイリアスの両方に一致する名前が含まれている場合、 GROUP BY 句は列名を使用します。これは、以下の例で示されています。

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

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

以下のクエリは、アクティブな従業員の給与合計と休暇中の従業員の給与合計を返します。

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

以下のクエリでは、クエリ内にあるテーブルの列の名前と一致するエイリアス state を使用しています。 state が GROUP BY で使用されている場合、Snowflakeはそれをエイリアスではなく列名への参照として解釈します。したがって、このクエリは、カリフォルニア州の従業員の給与合計とオレゴン州の従業員の給与合計を返しますが、employment_stateの情報(例:「アクティブ」)を州や県の名前の代わりに表示します。

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