GROUPBY関数の研究🤔～基本動作確認編～

# はじめに

すこし複雑なメジャーを記述しようとすると、避けては通れないテーブル操作関数。主要な`SUMMARIZE`、`ADDCOLUMNS`、 `SUMMARIZECOLUMNS`などを研究してみます。

**テーブル操作関数シリーズ**

続きものです。

1. [SUMMARIZE関数の研究～集計列の追加はなぜ非推奨なのか🤔～](https://qiita.com/akihiro_suto/items/a317d560fd298403bc15)
1. [ADDCOLUMNS関数の研究～集計列追加のベストプラクティス🤔～](https://qiita.com/akihiro_suto/items/ced4c9053f11fbe2baf3)
1. [集計列追加のベストプラクティス🤔～とはいえ例外だってあるぞ～](https://qiita.com/akihiro_suto/items/331aee0734b98c0ec345)
1. [SUMMARIZECOLUMNS関数の研究～SUMMARIZE関数は非推奨?🤔～](https://qiita.com/akihiro_suto/items/1a7c08aaf369ee1cc3a3)
1. [GROUPBY関数の研究🤔～基本動作確認編～](https://qiita.com/akihiro_suto/items/aaf2e4c98cf88833dc63)

## DAXクエリ＆DAX.do

https://dax.do/

今回の検証はDAX.do上でDAXクエリを書いて検証していきます。
DAXクエリがわからない方は先にこの記事を読んで、DAX.doで少し触ってからのほうが理解が進むでしょう。

DAXクエリについてはこちらの記事を参照してください。

https://qiita.com/hanaseleb/items/96b80210a7fc20c36a13

# 参考記事

https://www.sqlbi.com/articles/nested-grouping-using-groupby-vs-summarize/

# GROUPBY関数

## 文法

```
GROUPBY ( <Table> [, <GroupBy_ColumnName> [, [<Name>] [, [<Expression>] [, <GroupBy_ColumnName> [, [<Name>] [, [<Expression>] [, … ] ] ] ] ] ] ] )
```

# 使ってみる

'SUMMARIZE'関数などと同様最初の引数にはテーブルを指定する必要がある。

```
EVALUATE
GROUPBY ( 
    'Product',
    'Product'[Category],
    'Product'[Subcategory] 
)
```

結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/e26207ec-4bcc-9176-f42a-b41aaf949191.png)

## `SUMMARIZE`関数でも書ける

```
EVALUATE
SUMMARIZE ( 
    'Product',
    'Product'[Category],
    'Product'[Subcategory] 
)
```

結果は同じになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/e26207ec-4bcc-9176-f42a-b41aaf949191.png)

もちろん、`SUMMARIZECOLUMNS`関数でも同じ結果になります。

# 集計列の追加

次に集計列の追加をしてみます。
`'Product'[Category]`列でグループ化をして、それに売上列を追加します。

```
EVALUATE
GROUPBY (
    'Sales',
    'Product'[Category],
    "SalesAMT", 
    SUMX ( 
        CURRENTGROUP (),
        Sales[Net Price] * Sales[Quantity] )
)
ORDER BY
[SalesAMT] DESC
```

結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/78c40c36-30d1-6224-3f95-9b332f612cf4.png)

## `CURRENTGROUP()` ? 🤔

途中で見慣れぬ`CURRENTGROUP()`という関数がでてきました。これは、`GROUPBY`関数の現在のグループを表す (サブ) テーブルへのアクセスをします。**`GROUPBY`関数内でのみ使用できます。** 

## `SUMMARIZE`関数でも書ける

`SUMMARIZE`関数でも同じことが書けます。ただし、`CURRENTGROUP()` 関数は使えないので、改めて`SUMX`関数で集計してあげます。結果は同じ。

```
EVALUATE
SUMMARIZE (
    'Sales',
    'Product'[Category],
    "SalesAMT", 
    SUMX ( 
        Sales,
        Sales[Net Price] * Sales[Quantity] )
)
ORDER BY
[SalesAMT] DESC
```

## パフォーマンスの違い

DAX Studioで上記のクエリを実行してみると、パフォーマンスの違いがでる。

- `GROUPBY`関数
    - 78ms
- `SUMMARIZE`関数
    - 16ms

この計算の場合のパフォーマンスは`SUMMARIZE`関数に軍配が上がる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/44719739-5361-b47b-b58a-883ca2f71935.png)

# 集計列にメジャーを使用する

## `GROUPBY`関数

```
EVALUATE
GROUPBY (
    'Sales',
    'Product'[Category],
    "SalesAMT", [Sales Amount]
)
ORDER BY
[SalesAMT] DESC
```

### エラーが出る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/5910e680-ba6a-85cb-ef3b-124b4a24be88.png)

`GROUPBY`関数では集計列の追加にメジャーを指定することはできない😭
`CURRENTGROUP ()`関数を使用する必要がある。

## `SUMMARIZE`関数

```
EVALUATE
SUMMARIZE (
    'Sales',
    'Product'[Category],
    "SalesAMT", [Sales Amount]
)
ORDER BY
[SalesAMT] DESC
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/ab9457ec-44e7-3f47-3d40-9fba07127a11.png)

こちらは正しい数字がでる。作成済みのメジャーを使用した集計列の追加は可能。

# Docsを確認

https://learn.microsoft.com/ja-jp/dax/groupby-function-dax

**GROUPBY 関数は、SUMMARIZE 関数に似ています。**  ただし、GROUPBYでは、追加する拡張列に対して暗黙的な CALCULATE が実行されません。 GROUPBYでは、追加する拡張列の集計関数内で、新しい関数である CURRENTGROUP()を使用できます。 **GROUPBYは、1 つのテーブル スキャンで、複数の集計を実行するために使用されます。**

# 今日のまとめ

グループ化して、簡単な集計列を追加するだけであれば、`SUMMARIZE`関数の使用が推奨されるようです。既存のメジャーも使えないし、パフォーマンスも劣るからです。
次回記事では、`GROUPBY`関数の使い所を探ります。