カテゴリ:

クエリ構文

GROUP BY

同じグループごとの式で行をグループ化し、結果のグループの集計関数を計算します。GROUP BY 式は、列名、 SELECT リスト内の位置を参照する数値、または一般式です。

拡張機能:

GROUP BY CUBEGROUP BY GROUPING SETSGROUP BY ROLLUP

構文

SELECT ...
FROM ...
[ ... ]
GROUP BY groupItem [ , groupItem> [ , ... ] ]
[ ... ]

条件:

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

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

position

SELECT リスト内の式の位置。

expr

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

使用上の注意

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

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

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

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

1列でグループ化

この例では、製品ごとの総収益を product_id でグループ化して示しています。

-- Create the sales table and insert some rows.
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');

-- Show the gross revenue, grouped by product_id.
-- In other words, show the total amount of money received for
-- selling each product.
SELECT product_ID, SUM(retail_price * quantity) AS gross_revenue
  FROM sales
  GROUP BY product_ID;

出力:

+------------+---------------+
| PRODUCT_ID | GROSS_REVENUE |
+============+===============+
|          1 |          6    |
+------------+---------------+
|          2 |        620    |
+------------+---------------+

この例は、前の例に基づいており、製品ごとの純利益を product_id でグループ化して示しています。

-- Create the products table and insert some rows.
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);

-- Show the net profit on each product.
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;

出力:

+------------+--------+
| PRODUCT_ID | PROFIT |
+============+========+
|          1 |      3 |
+------------+--------+
|          2 |    372 |
+------------+--------+

複数の列でグループ化

複数の列でグループ化できます。

SELECT State, City, SUM(retail_price * quantity) AS gross_revenue
 FROM sales
 GROUP BY State, City;

出力:

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

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

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

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

以下のクエリでは、クエリ内にあるテーブルの列の名前と一致するエイリアス 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 |
+-------------+--------+
最上部に戻る