ClickHouse/docs/ja/sql-reference/aggregate-functions/grouping_function.md

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

349 lines
13 KiB
Markdown
Raw Permalink Normal View History

2024-11-18 02:58:58 +00:00
---
slug: /ja/sql-reference/aggregate-functions/grouping_function
---
# GROUPING
## GROUPING
[ROLLUP](../statements/select/group-by.md/#rollup-modifier) と [CUBE](../statements/select/group-by.md/#cube-modifier) は、GROUP BY に対する修飾子です。これらの修飾子は、いずれも小計を計算します。ROLLUP はカラムの並べられたリスト、例えば `(day, month, year)` を取り、集計の各レベルで小計を計算した後、総計を算出します。CUBE は、指定されたカラムの全ての可能な組み合わせにわたって小計を計算します。GROUPING は、ROLLUP または CUBE によって戻された行がスーパー集計であるかどうかを識別し、修飾されていない GROUP BY で戻される行であるかどうかを識別します。
GROUPING 関数は、複数のカラムを引数として受け取り、ビットマスクを返します。
- `1` は、`GROUP BY` に対する `ROLLUP` または `CUBE` 修飾子によって戻された行が小計であることを示します
- `0` は、`ROLLUP` または `CUBE` によって戻された行が小計でないことを示します
## GROUPING SETS
デフォルトでは、CUBE 修飾子は、CUBE に渡されたカラムのすべての可能な組み合わせに対して小計を計算します。GROUPING SETS を使用すると、計算する特定の組み合わせを指定できます。
階層データの分析には、ROLLUP、CUBE、および GROUPING SETS 修飾子を使用することがおすすめです。ここでのサンプルは、2つのデータセンターにインストールされている Linux ディストリビューションとそのバージョンに関するデータを含むテーブルです。このデータをディストリビューション、バージョン、および場所別で見ることが有益かもしれません。
### サンプルデータのロード
```sql
CREATE TABLE servers ( datacenter VARCHAR(255),
distro VARCHAR(255) NOT NULL,
version VARCHAR(50) NOT NULL,
quantity INT
)
ORDER BY (datacenter, distro, version)
```
```sql
INSERT INTO servers(datacenter, distro, version, quantity)
VALUES ('Schenectady', 'Arch','2022.08.05',50),
('Westport', 'Arch','2022.08.05',40),
('Schenectady','Arch','2021.09.01',30),
('Westport', 'Arch','2021.09.01',20),
('Schenectady','Arch','2020.05.01',10),
('Westport', 'Arch','2020.05.01',5),
('Schenectady','RHEL','9',60),
('Westport','RHEL','9',70),
('Westport','RHEL','7',80),
('Schenectady','RHEL','7',80)
```
```sql
SELECT
*
FROM
servers;
```
```response
┌─datacenter──┬─distro─┬─version────┬─quantity─┐
│ Schenectady │ Arch │ 2020.05.01 │ 10 │
│ Schenectady │ Arch │ 2021.09.01 │ 30 │
│ Schenectady │ Arch │ 2022.08.05 │ 50 │
│ Schenectady │ RHEL │ 7 │ 80 │
│ Schenectady │ RHEL │ 9 │ 60 │
│ Westport │ Arch │ 2020.05.01 │ 5 │
│ Westport │ Arch │ 2021.09.01 │ 20 │
│ Westport │ Arch │ 2022.08.05 │ 40 │
│ Westport │ RHEL │ 7 │ 80 │
│ Westport │ RHEL │ 9 │ 70 │
└─────────────┴────────┴────────────┴──────────┘
10 rows in set. Elapsed: 0.409 sec.
```
### シンプルなクエリ
ディストリビューションごとに各データセンターのサーバー数を取得:
```sql
SELECT
datacenter,
distro,
SUM (quantity) qty
FROM
servers
GROUP BY
datacenter,
distro;
```
```response
┌─datacenter──┬─distro─┬─qty─┐
│ Schenectady │ RHEL │ 140 │
│ Westport │ Arch │ 65 │
│ Schenectady │ Arch │ 90 │
│ Westport │ RHEL │ 150 │
└─────────────┴────────┴─────┘
4 rows in set. Elapsed: 0.212 sec.
```
```sql
SELECT
datacenter,
SUM (quantity) qty
FROM
servers
GROUP BY
datacenter;
```
```response
┌─datacenter──┬─qty─┐
│ Westport │ 215 │
│ Schenectady │ 230 │
└─────────────┴─────┘
2 rows in set. Elapsed: 0.277 sec.
```
```sql
SELECT
distro,
SUM (quantity) qty
FROM
servers
GROUP BY
distro;
```
```response
┌─distro─┬─qty─┐
│ Arch │ 155 │
│ RHEL │ 290 │
└────────┴─────┘
2 rows in set. Elapsed: 0.352 sec.
```
```sql
SELECT
SUM(quantity) qty
FROM
servers;
```
```response
┌─qty─┐
│ 445 │
└─────┘
1 row in set. Elapsed: 0.244 sec.
```
### 複数の GROUP BY 文と GROUPING SETS の比較
CUBE、ROLLUP、または GROUPING SETS を使用せずにデータを分解:
```sql
SELECT
datacenter,
distro,
SUM (quantity) qty
FROM
servers
GROUP BY
datacenter,
distro
UNION ALL
SELECT
datacenter,
null,
SUM (quantity) qty
FROM
servers
GROUP BY
datacenter
UNION ALL
SELECT
null,
distro,
SUM (quantity) qty
FROM
servers
GROUP BY
distro
UNION ALL
SELECT
null,
null,
SUM(quantity) qty
FROM
servers;
```
```response
┌─datacenter─┬─distro─┬─qty─┐
│ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ 445 │
└────────────┴────────┴─────┘
┌─datacenter──┬─distro─┬─qty─┐
│ Westport │ ᴺᵁᴸᴸ │ 215 │
│ Schenectady │ ᴺᵁᴸᴸ │ 230 │
└─────────────┴────────┴─────┘
┌─datacenter──┬─distro─┬─qty─┐
│ Schenectady │ RHEL │ 140 │
│ Westport │ Arch │ 65 │
│ Schenectady │ Arch │ 90 │
│ Westport │ RHEL │ 150 │
└─────────────┴────────┴─────┘
┌─datacenter─┬─distro─┬─qty─┐
│ ᴺᵁᴸᴸ │ Arch │ 155 │
│ ᴺᵁᴸᴸ │ RHEL │ 290 │
└────────────┴────────┴─────┘
9 rows in set. Elapsed: 0.527 sec.
```
GROUPING SETS を使用して同じ情報を取得:
```sql
SELECT
datacenter,
distro,
SUM (quantity) qty
FROM
servers
GROUP BY
GROUPING SETS(
(datacenter,distro),
(datacenter),
(distro),
()
)
```
```response
┌─datacenter──┬─distro─┬─qty─┐
│ Schenectady │ RHEL │ 140 │
│ Westport │ Arch │ 65 │
│ Schenectady │ Arch │ 90 │
│ Westport │ RHEL │ 150 │
└─────────────┴────────┴─────┘
┌─datacenter──┬─distro─┬─qty─┐
│ Westport │ │ 215 │
│ Schenectady │ │ 230 │
└─────────────┴────────┴─────┘
┌─datacenter─┬─distro─┬─qty─┐
│ │ │ 445 │
└────────────┴────────┴─────┘
┌─datacenter─┬─distro─┬─qty─┐
│ │ Arch │ 155 │
│ │ RHEL │ 290 │
└────────────┴────────┴─────┘
9 rows in set. Elapsed: 0.427 sec.
```
### CUBE と GROUPING SETS の比較
次のクエリにおける CUBE `CUBE(datacenter,distro,version)` は、意味をなさない階層を提供しています。2つのディストリビューションにわたってバージョンを見ることは意味をなさないかもしれませんなぜなら Arch と RHEL は同じリリースサイクルやバージョン命名標準を持っていないためです。次の例で示すように、GROUPING SETS を使用すると、`distro` と `version` を同じセットでグループ化することができ、より適切です。
```sql
SELECT
datacenter,
distro,
version,
SUM(quantity)
FROM
servers
GROUP BY
CUBE(datacenter,distro,version)
ORDER BY
datacenter,
distro;
```
```response
┌─datacenter──┬─distro─┬─version────┬─sum(quantity)─┐
│ │ │ 7 │ 160 │
│ │ │ 2020.05.01 │ 15 │
│ │ │ 2021.09.01 │ 50 │
│ │ │ 2022.08.05 │ 90 │
│ │ │ 9 │ 130 │
│ │ │ │ 445 │
│ │ Arch │ 2021.09.01 │ 50 │
│ │ Arch │ 2022.08.05 │ 90 │
│ │ Arch │ 2020.05.01 │ 15 │
│ │ Arch │ │ 155 │
│ │ RHEL │ 9 │ 130 │
│ │ RHEL │ 7 │ 160 │
│ │ RHEL │ │ 290 │
│ Schenectady │ │ 9 │ 60 │
│ Schenectady │ │ 2021.09.01 │ 30 │
│ Schenectady │ │ 7 │ 80 │
│ Schenectady │ │ 2022.08.05 │ 50 │
│ Schenectady │ │ 2020.05.01 │ 10 │
│ Schenectady │ │ │ 230 │
│ Schenectady │ Arch │ 2022.08.05 │ 50 │
│ Schenectady │ Arch │ 2021.09.01 │ 30 │
│ Schenectady │ Arch │ 2020.05.01 │ 10 │
│ Schenectady │ Arch │ │ 90 │
│ Schenectady │ RHEL │ 7 │ 80 │
│ Schenectady │ RHEL │ 9 │ 60 │
│ Schenectady │ RHEL │ │ 140 │
│ Westport │ │ 9 │ 70 │
│ Westport │ │ 2020.05.01 │ 5 │
│ Westport │ │ 2022.08.05 │ 40 │
│ Westport │ │ 7 │ 80 │
│ Westport │ │ 2021.09.01 │ 20 │
│ Westport │ │ │ 215 │
│ Westport │ Arch │ 2020.05.01 │ 5 │
│ Westport │ Arch │ 2021.09.01 │ 20 │
│ Westport │ Arch │ 2022.08.05 │ 40 │
│ Westport │ Arch │ │ 65 │
│ Westport │ RHEL │ 9 │ 70 │
│ Westport │ RHEL │ 7 │ 80 │
│ Westport │ RHEL │ │ 150 │
└─────────────┴────────┴────────────┴───────────────┘
39 rows in set. Elapsed: 0.355 sec.
```
:::note
上記の例のバージョンは、distro に関連していない場合には意味をなさないかもしれませんが、カーネルバージョンを追跡している場合には意味をなすかもしれません。なぜなら、カーネルバージョンはどちらのディストリビューションにも関連付けられる可能性があるからです。次の例のように GROUPING SETS を使用する方が適している場合があります。
:::
```sql
SELECT
datacenter,
distro,
version,
SUM(quantity)
FROM servers
GROUP BY
GROUPING SETS (
(datacenter, distro, version),
(datacenter, distro))
```
```response
┌─datacenter──┬─distro─┬─version────┬─sum(quantity)─┐
│ Westport │ RHEL │ 9 │ 70 │
│ Schenectady │ Arch │ 2022.08.05 │ 50 │
│ Schenectady │ Arch │ 2021.09.01 │ 30 │
│ Schenectady │ RHEL │ 7 │ 80 │
│ Westport │ Arch │ 2020.05.01 │ 5 │
│ Westport │ RHEL │ 7 │ 80 │
│ Westport │ Arch │ 2021.09.01 │ 20 │
│ Westport │ Arch │ 2022.08.05 │ 40 │
│ Schenectady │ RHEL │ 9 │ 60 │
│ Schenectady │ Arch │ 2020.05.01 │ 10 │
└─────────────┴────────┴────────────┴───────────────┘
┌─datacenter──┬─distro─┬─version─┬─sum(quantity)─┐
│ Schenectady │ RHEL │ │ 140 │
│ Westport │ Arch │ │ 65 │
│ Schenectady │ Arch │ │ 90 │
│ Westport │ RHEL │ │ 150 │
└─────────────┴────────┴─────────┴───────────────┘
14 rows in set. Elapsed: 1.036 sec.
```