多次元データの集約と分析において、列 a を集約し、列 b を集約し、さらに列 a と列 b を集約する場合、GROUPING SETS を使用してこれらの操作を実行できます。このトピックでは、多次元集約に GROUPING SETS を使用する方法について説明します。
説明
GROUPING SETS は、SELECT 文の GROUP BY 句の拡張です。GROUPING SETS 句を使用すると、複数の SELECT 文と UNION ALL を順番に実行する必要なく、結果を複数の方法でグループ化できます。これにより、MaxCompute はより効率的な実行計画を生成し、パフォーマンスを向上させることができます。
次の表は、GROUPING SETS に関連付けられている構文を示しています。
タイプ | 説明 |
|
|
|
|
|
|
|
|
|
説明 Hive 2.3.0 以降を使用している場合は、MaxCompute でこの関数を使用することをお勧めします。Hive 2.3.0 より前のバージョンを使用している場合は、MaxCompute でこの関数を使用しないことをお勧めします。 |
例
GROUPING SETS の使用例:
データを準備します。
create table requests lifecycle 20 as select * from values (1, 'windows', 'PC', 'Beijing'), (2, 'windows', 'PC', 'Shijiazhuang'), (3, 'linux', 'Phone', 'Beijing'), (4, 'windows', 'PC', 'Beijing'), (5, 'ios', 'Phone', 'Shijiazhuang'), (6, 'linux', 'PC', 'Beijing'), (7, 'windows', 'Phone', 'Shijiazhuang') as t(id, os, device, city); /* id、OS、デバイス、都市のデータを格納する requests テーブルを作成 */次のいずれかの方法を使用してデータをグループ化します。
複数の
SELECT文を実行してデータをグループ化します。select NULL, NULL, NULL, count(*) from requests union all select os, device, NULL, count(*) from requests group by os, device union all select null, null, city, count(*) from requests group by city;GROUPING SETSを使用してデータをグループ化します。select os,device, city ,count(*) from requests group by grouping sets((os, device), (city), ());次の結果が返されます。
+------------+------------+------------+------------+ | os | device | city | _c3 | +------------+------------+------------+------------+ | NULL | NULL | NULL | 7 | | NULL | NULL | Beijing | 4 | | NULL | NULL | Shijiazhuang | 3 | | ios | Phone | NULL | 1 | | linux | PC | NULL | 1 | | linux | Phone | NULL | 1 | | windows | PC | NULL | 3 | | windows | Phone | NULL | 1 | +------------+------------+------------+------------+
説明GROUPING SETS で一部の式が使用されていない場合、これらの式のプレースホルダーとして NULL が使用されます。たとえば、4 行目から 8 行目の city 列の NULL です。このようにして、結果セットに対して操作を実行できます。
CUBE または ROLLUP を使用する場合の例
GROUPING SETS の構文に基づいて CUBE または ROLLUP を使用する場合の例:
例 1:
CUBEを使用して、すべての可能な列os、device、cityをgrouping setsとしてリストします。select os,device, city, count(*) from requests group by cube (os, device, city); -- 前述のステートメントは、次のステートメントと同等です。 select os,device, city, count(*) from requests group by grouping sets ((os, device, city),(os, device),(os, city),(device,city),(os),(device),(city),());次の結果が返されます。
+------------+------------+------------+------------+ | os | device | city | _c3 | +------------+------------+------------+------------+ | NULL | NULL | NULL | 7 | | NULL | NULL | Beijing | 4 | | NULL | NULL | Shijiazhuang | 3 | | NULL | PC | NULL | 4 | | NULL | PC | Beijing | 3 | | NULL | PC | Shijiazhuang | 1 | | NULL | Phone | NULL | 3 | | NULL | Phone | Beijing | 1 | | NULL | Phone | Shijiazhuang | 2 | | ios | NULL | NULL | 1 | | ios | NULL | Shijiazhuang | 1 | | ios | Phone | NULL | 1 | | ios | Phone | Shijiazhuang | 1 | | linux | NULL | NULL | 2 | | linux | NULL | Beijing | 2 | | linux | PC | NULL | 1 | | linux | PC | Beijing | 1 | | linux | Phone | NULL | 1 | | linux | Phone | Beijing | 1 | | windows | NULL | NULL | 4 | | windows | NULL | Beijing | 2 | | windows | NULL | Shijiazhuang | 2 | | windows | PC | NULL | 3 | | windows | PC | Beijing | 2 | | windows | PC | Shijiazhuang | 1 | | windows | Phone | NULL | 1 | | windows | Phone | Shijiazhuang | 1 | +------------+------------+------------+------------+例 2:
CUBEを使用して、列(os, device)と(device, city)のすべての可能な組み合わせをgrouping setsとしてリストします。select os,device, city, count(*) from requests group by cube ((os, device), (device, city)); -- 前述のステートメントは、次のステートメントと同等です。 select os,device, city, count(*) from requests group by grouping sets ((os, device, city),(os, device),(device,city),());次の結果が返されます。
+------------+------------+------------+------------+ | os | device | city | _c3 | +------------+------------+------------+------------+ | NULL | NULL | NULL | 7 | | NULL | PC | Beijing | 3 | | NULL | PC | Shijiazhuang | 1 | | NULL | Phone | Beijing | 1 | | NULL | Phone | Shijiazhuang | 2 | | ios | Phone | NULL | 1 | | ios | Phone | Shijiazhuang | 1 | | linux | PC | NULL | 1 | | linux | PC | Beijing | 1 | | linux | Phone | NULL | 1 | | linux | Phone | Beijing | 1 | | windows | PC | NULL | 3 | | windows | PC | Beijing | 2 | | windows | PC | Shijiazhuang | 1 | | windows | Phone | NULL | 1 | | windows | Phone | Shijiazhuang | 1 | +------------+------------+------------+------------+例 3:
ROLLUPを使用して、os、device、city列を階層的に集約し、複数のgrouping setsを生成します。select os,device, city, count(*) from requests group by rollup (os, device, city); -- 前述のステートメントは、次のステートメントと同等です。 select os,device, city, count(*) from requests group by grouping sets ((os, device, city),(os, device),(os),());次の結果が返されます。
+------------+------------+------------+------------+ | os | device | city | _c3 | +------------+------------+------------+------------+ | NULL | NULL | NULL | 7 | | ios | NULL | NULL | 1 | | ios | Phone | NULL | 1 | | ios | Phone | Shijiazhuang | 1 | | linux | NULL | NULL | 2 | | linux | PC | NULL | 1 | | linux | PC | Beijing | 1 | | linux | Phone | NULL | 1 | | linux | Phone | Beijing | 1 | | windows | NULL | NULL | 4 | | windows | PC | NULL | 3 | | windows | PC | Beijing | 2 | | windows | PC | Shijiazhuang | 1 | | windows | Phone | NULL | 1 | | windows | Phone | Shijiazhuang | 1 | +------------+------------+------------+------------+例 4:
ROLLUPを使用して、os、(os,device)、cityを階層的に集約し、複数のgrouping setsを生成します。select os,device, city, count(*) from requests group by rollup (os, (os,device), city); -- 前述のステートメントは、次のステートメントと同等です。 select os,device, city, count(*) from requests group by grouping sets ((os, device, city),(os, device),(os),());次の結果が返されます。
+------------+------------+------------+------------+ | os | device | city | _c3 | +------------+------------+------------+------------+ | NULL | NULL | NULL | 7 | | ios | NULL | NULL | 1 | | ios | Phone | NULL | 1 | | ios | Phone | Shijiazhuang | 1 | | linux | NULL | NULL | 2 | | linux | PC | NULL | 1 | | linux | PC | Beijing | 1 | | linux | Phone | NULL | 1 | | linux | Phone | Beijing | 1 | | windows | NULL | NULL | 4 | | windows | PC | NULL | 3 | | windows | PC | Beijing | 2 | | windows | PC | Shijiazhuang | 1 | | windows | Phone | NULL | 1 | | windows | Phone | Shijiazhuang | 1 | +------------+------------+------------+------------+例 5:
GROUP BY、CUBE、GROUPING SETSを使用して、複数のgrouping setsを生成します。select os,device, city, count(*) from requests group by os, cube(os,device), grouping sets(city); -- 前述のステートメントは、次のステートメントと同等です。 select os,device, city, count(*) from requests group by grouping sets((os,device,city),(os,city),(os,device,city));次の結果が返されます。
+------------+------------+------------+------------+ | os | device | city | _c3 | +------------+------------+------------+------------+ | ios | NULL | Shijiazhuang | 1 | | ios | Phone | Shijiazhuang | 1 | | linux | NULL | Beijing | 2 | | linux | PC | Beijing | 1 | | linux | Phone | Beijing | 1 | | windows | NULL | Beijing | 2 | | windows | NULL | Shijiazhuang | 2 | | windows | PC | Beijing | 2 | | windows | PC | Shijiazhuang | 1 | | windows | Phone | Shijiazhuang | 1 | +------------+------------+------------+------------+
GROUPING と GROUPING_ID を使用する場合の例
サンプルステートメント:
select a,b,c,count(*),
grouping(a) ga, grouping(b) gb, grouping(c) gc, grouping_id(a,b,c) groupingid
from values (1,2,3) as t(a,b,c)
group by cube(a,b,c);次の結果が返されます。
+------------+------------+------------+------------+------------+------------+------------+------------+
| a | b | c | _c3 | ga | gb | gc | groupingid |
+------------+------------+------------+------------+------------+------------+------------+------------+
| NULL | NULL | NULL | 1 | 1 | 1 | 1 | 7 |
| NULL | NULL | 3 | 1 | 1 | 1 | 0 | 6 |
| NULL | 2 | NULL | 1 | 1 | 0 | 1 | 5 |
| NULL | 2 | 3 | 1 | 1 | 0 | 0 | 4 |
| 1 | NULL | NULL | 1 | 0 | 1 | 1 | 3 |
| 1 | NULL | 3 | 1 | 0 | 1 | 0 | 2 |
| 1 | 2 | NULL | 1 | 0 | 0 | 1 | 1 |
| 1 | 2 | 3 | 1 | 0 | 0 | 0 | 0 |
+------------+------------+------------+------------+------------+------------+------------+------------+デフォルトでは、GROUP BY で指定されていない列には NULL が入力されます。GROUPING を使用して、必要な値を指定できます。GROUPING SETS の構文に基づくサンプルステートメント:
select
if(grouping(os) == 0, os, 'ALL') as os, /* os でグループ化されていない場合は os の値を、そうでない場合は 'ALL' を返す */
if(grouping(device) == 0, device, 'ALL') as device, /* device でグループ化されていない場合は device の値を、そうでない場合は 'ALL' を返す */
if(grouping(city) == 0, city, 'ALL') as city, /* city でグループ化されていない場合は city の値を、そうでない場合は 'ALL' を返す */
count(*) as count
from requests
group by os, device, city grouping sets((os, device), (city), ());次の結果が返されます。
+------------+------------+------------+------------+
| os | device | city | count |
+------------+------------+------------+------------+
| ALL | ALL | ALL | 7 |
| ALL | ALL | Beijing | 4 |
| ALL | ALL | Shijiazhuang | 3 |
| ios | Phone | ALL | 1 |
| linux | PC | ALL | 1 |
| linux | Phone | ALL | 1 |
| windows | PC | ALL | 3 |
| windows | Phone | ALL | 1 |
+------------+------------+------------+------------+GROUPING__ID を使用する場合の例
パラメーターを指定せずに GROUPING__ID を使用する場合の例:
set odps.sql.hive.compatible=true;
select
a, b, c, count(*), grouping__id
from values (1,2,3) as t(a,b,c)
group by a, b, c grouping sets ((a,b,c), (a));
-- 前述のステートメントは、次のステートメントと同等です。
select
a, b, c, count(*), grouping_id(a,b,c)
from values (1,2,3) as t(a,b,c)
group by a, b, c grouping sets ((a,b,c), (a));次の結果が返されます。
+------------+------------+------------+------------+------------+
| a | b | c | _c3 | _c4 |
+------------+------------+------------+------------+------------+
| 1 | NULL | NULL | 1 | 3 |
| 1 | 2 | 3 | 1 | 0 |
+------------+------------+------------+------------+------------+