多次元データ集計および分析では、列 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); -
次のいずれかの方法でデータをグループ化します:
-
複数の
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を使用して、grouping setsとして、列のすべての可能な組み合わせ ((os, device)と(device, city)) を一覧表示します。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列を階層的に集計し、複数のグルーピングセットを生成します。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を使用して複数のグループ化セットを生成します。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 | _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,
if(grouping(device) == 0, device, 'ALL') as device,
if(grouping(city) == 0, city, 'ALL') as city,
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 |
+------------+------------+------------+------------+------------+