すべてのプロダクト
Search
ドキュメントセンター

AnalyticDB:GROUP BY

最終更新日:Mar 15, 2025

GROUP BY 句を使用すると、指定した列に基づいて集計結果をグループ化できます。また、GROUP BY 句で GROUPING SETSWITH CUBE、または ROLLUP オプションを使用して、グループ化結果をさまざまな形式で表示することもできます。

GROUP BY expression [, ...]    

使用上の注意

  • GROUP BY 以外の列を宣言するには、SUM()AVG()COUNT() などの標準 集計関数 を使用する必要があります。使用しない場合、ARBITRARY() 関数を使用して、GROUP BY 以外の列がランダムに返されます。

  • AnalyticDB for MySQL では、ONLY_FULL_GROUP_BY モードはサポートされていません。

GROUPING SETS

GROUPING SETS オプションを使用すると、同じデータセットに対して複数のディメンションで集計を実行し、結果を 1 つの結果セットに結合できます。GROUPING SETS オプションを使用すると、1 つのクエリに複数の GROUP BY 条件を指定できます。これは、複数の GROUP BY 句の union と同じです。

SELECT origin_state, origin_zip, destination_state, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
    (origin_state),
    (origin_state, origin_zip),
    (destination_state));         

上記の文は、次の文と同じです。

SELECT origin_state, NULL, NULL, sum(package_weight)
FROM shipping GROUP BY origin_state
UNION ALL
SELECT origin_state, origin_zip, NULL, sum(package_weight)
FROM shipping GROUP BY origin_state, origin_zip
UNION ALL
SELECT NULL, NULL, destination_state, sum(package_weight)
FROM shipping GROUP BY destination_state;       

CUBE

CUBE オプションは GROUPING SETS オプションに似ていますが、CUBE オプションは、グループを手動で指定する必要なく、すべての可能なグループ化セットを自動的に生成します。

SELECT origin_state, destination_state, sum(package_weight)
FROM shipping
GROUP BY origin_state, destination_state WITH CUBE;    

上記の文は、次の文と同じです。

SELECT origin_state, destination_state, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
    (origin_state, destination_state),
    (origin_state),
    (destination_state),
    ());        

ROLLUP

ROLLUP オプションは、各 GROUP BY 列に対して階層的なグループ化セットを生成します。グループ化のディメンションは、指定された列の順序で徐々に縮小され、全体的なサマリーが生成されます。

SELECT origin_state, origin_zip, destination_state, SUM(package_weight)
FROM shipping
GROUP BY ROLLUP (origin_state, origin_zip, destination_state);          

上記の文は、次の文と同じです。

SELECT origin_state, origin_zip, destination_state, SUM(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
    (origin_state, origin_zip, destination_state),
    (origin_state, origin_zip), 
    (origin_state), 
    ()
    );          

使用上の注意

AnalyticDB for MySQL では、GROUP BY ROLLUP (...) の後に列名を続けることはできません。たとえば、次の文を実行するとエラーが発生します。

SELECT origin_state, origin_zip, destination_state, SUM(package_weight)
FROM shipping
GROUP BY ROLLUP (origin_state, origin_zip), destination_state;

GROUP BY 句の union を階層的に実装する場合は、GROUP BY GROUPING SETS ((origin_state, origin_zip), (origin_state), ()), destination_state 句を指定できます。

次の例は、GROUP BY 句、GROUP SETSWITH CUBEROLLUP オプションを使用した場合の効果を示しています。これらの例では、sales テーブルを使用します。

次の文を実行して、sales という名前のテーブルを作成し、sales テーブルにデータを挿入します。

CREATE TABLE sales (
    year INT,
    region VARCHAR(50),
    amount DECIMAL(10, 2)
);

INSERT INTO sales (year, region, amount) VALUES
(2020, 'North', 1000.00),
(2020, 'South', 1500.00),
(2020, 'East', 1200.00),
(2020, 'West', 1300.00),
(2021, 'North', 2000.00),
(2021, 'South', 2500.00),
(2021, 'East', 2200.00),
(2021, 'West', 2300.00),
(2022, 'North', 3000.00),
(2022, 'South', 3500.00),
(2022, 'East', 3200.00),
(2022, 'West', 3300.00);

例 1:GROUP BY 句を使用してデータをクエリします。

次の文を実行して、year 列と region 列でグループ化された amount 列の合計値をクエリします。

SELECT year, region, SUM(amount) as sum_amount
FROM sales
GROUP BY year, region
ORDER BY 3,2, 1 -- 結果をこの順序でソートします。sum_amount 列、region 列、year 列。
LIMIT 5;

結果例:

year | region | sum_amount 
-----+--------+------------
2020 |  North |   1000.00  
2020 |  East  |   1200.00  
2020 |  West  |   1300.00  
2020 |  South |   1500.00  
2021 |  North |   2000.00  
(5 rows)         

GROUP BY 句では、シーケンス番号を使用して列を参照することもできます。上記の文を次の文に変更できます。

SELECT year, region, SUM(amount) as sum_amount
FROM sales
GROUP BY 1,2 -- year 列と region 列で結果をグループ化します。
ORDER BY 3, 2, 1
LIMIT 5;       

結果例:

year | region | sum_amount 
-----+--------+------------
2020 |  North |   1000.00  
2020 |  East  |   1200.00  
2020 |  West  |   1300.00  
2020 |  South |   1500.00  
2021 |  North |   2000.00  
(5 rows)         

例 2:次の文を実行して、year 列と region 列によるグループ化結果、year 列によるグループ化結果、region 列によるグループ化結果、および全体的なサマリー結果を、GROUPING SETS オプションを使用して 1 つの結果セットに結合します。

SELECT year, region, SUM(amount) as sum_amount
FROM sales
GROUP BY GROUPING SETS (
    (year,region), -- year 列と region 列で結果をグループ化します。
    (region), -- region 列で結果をグループ化します。
    (year), -- year 列で結果をグループ化します。
    () -- 全体的なサマリー結果を生成します。
    );

結果例:

year | region | sum_amount 
-----+--------+------------
2020 |  North |   1000.00  
2020 |  East  |   1200.00  
2020 |  West  |   1300.00  
2020 |  South |   1500.00  
2021 |  North |   2000.00
2021 |  East  |   2200.00  
2021 |  West  |   2300.00  
2021 |  South |   2500.00  
2022 |  North |   3000.00  
2022 |  East  |   3200.00  
2022 |  West  |   3300.00  
2022 |  South |   3500.00
NULL |  North |   6000.00  
NULL |  East  |   6600.00  
NULL |  West  |   6900.00  
NULL |  South |   7500.00
2020 |  NULL  |   5000.00  
2021 |  NULL  |   9000.00
2022 |  NULL  |  13000.00
NULL |  NULL  |  27000.00
(20 rows)         

例 3:GROUP BY ... WITH CUBE 句を使用して次の文を実行し、すべての可能なグループ化セットを生成します。これは、GROUPING SETS オプションを使用した例 2 と同じ効果があります。

SELECT year, region, SUM(amount) as sum_amount
FROM sales
GROUP BY year,region WITH CUBE;

結果例:

year | region | sum_amount 
-----+--------+------------
2020 |  North |   1000.00  
2020 |  East  |   1200.00  
2020 |  West  |   1300.00  
2020 |  South |   1500.00  
2021 |  North |   2000.00
2021 |  East  |   2200.00  
2021 |  West  |   2300.00  
2021 |  South |   2500.00  
2022 |  North |   3000.00  
2022 |  East  |   3200.00  
2022 |  West  |   3300.00  
2022 |  South |   3500.00
NULL |  North |   6000.00  
NULL |  East  |   6600.00  
NULL |  West  |   6900.00  
NULL |  South |   7500.00
2020 |  NULL  |   5000.00  
2021 |  NULL  |   9000.00
2022 |  NULL  |  13000.00
NULL |  NULL  |  27000.00
(20 rows)         

例 4:GROUP BY ROLLUP(...) 句を使用して次の文を実行し、最も詳細なサマリー結果 (year 列と region 列で集計) を生成し、次にグループ化ディメンションを徐々に縮小 (year 列で集計) し、最後に全体的なサマリー結果を生成します。

SELECT year, region, SUM(amount) as sum_amount
FROM sales
GROUP BY ROLLUP(year,region);

結果例:

year | region | sum_amount 
-----+--------+------------
2020 |  North |   1000.00  
2020 |  East  |   1200.00  
2020 |  West  |   1300.00  
2020 |  South |   1500.00  
2021 |  North |   2000.00
2021 |  East  |   2200.00  
2021 |  West  |   2300.00  
2021 |  South |   2500.00  
2022 |  North |   3000.00  
2022 |  East  |   3200.00  
2022 |  West  |   3300.00  
2022 |  South |   3500.00
2020 |  NULL  |   5000.00  
2021 |  NULL  |   9000.00
2022 |  NULL  |  13000.00
NULL |  NULL  |  27000.00
(16 rows)