【BI】Metabase使ってみた

### 前置き
業務でMetabaseを利用する機会があったので自習と業務での知見を備忘としてまとめた。

## Metabaseとは
オープンソースのBIツール
DBと接続してダッシュボードを作成し、データを可視化できるツールである。
執筆時点ではオンプレ版で無料のOSS～有償のEnterpriseプランの3プランと、Cloud版の有償3プランがある。

https://www.metabase.com/

## 特徴
BIツールとしては後発ゆえか、モダンなUIで直感的に操作が可能。
Metabaseではデータの抽出・可視化を「質問」と呼び、その方法は
* GUIでの抽出・可視化
* SQLでの抽出・可視化

の2種類である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/bb253bc0-e61c-b30a-0652-acc2f8a56733.png)


SQLが使えない・不慣れな担当者でも簡単にデータの可視化が可能である。
SQLに慣れ親しんだアナリスト・データサイエンティスト・データエンジニアはSQLでの可視化も可能。
他のBIとしてTableauを利用していた自分にとってはネイティブなSQLでデータを集計できるのがありがたかった。

## 使い方
今回個人環境ではDockerイメージを利用して実行環境を作成した。
オンプレ版はDockerイメージでの利用と、Jarファイルでの利用が可能。

https://www.metabase.com/start/oss/

左下設定の管理者設定から認証やDBへの接続などが操作可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/389cbd6c-c8f1-22b1-6e45-54f0c8fae0e8.png)

今回は用意されているサンプルのデータセットで試した。

[特徴](#特徴)の項でも触れたが、「質問」でのGUIでのデータ抽出とSQLクエリでの抽出がある。

### １．GUIでの抽出
* データ（DBでいうテーブル）を選択（結合も可）
* 集計したい列と集計方法の選択
* 集約のキー列の選択
* その他ソートなどのオプションの選択

といった数ステップでデータが簡単に集計・抽出できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/915f4a7c-7dc4-6421-2f52-94de0a046a79.png)

そのままでは表形式で結果が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/2c296598-a0f2-c7f7-601e-c2228a21c6e1.png)

ビジュアライゼーションより可視化方法を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/79d1e57c-f130-7af3-c574-442ee6d0eecf.png)

描画タイプ：線、X軸：日付の列・カテゴリー、Y軸：売上の集計値を選択
すると、簡単にカテゴリー別の売り上げ推移のグラフが作成できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/a1704020-5ce2-5281-56c1-8e9034ed959b.png)

※実は裏でSQLが作成されている
```
SELECT parsedatetime(formatdatetime("PUBLIC"."ORDERS"."CREATED_AT", 'yyyyMM'), 'yyyyMM') AS "CREATED_AT", "Products"."CATEGORY" AS "Products__CATEGORY", sum("PUBLIC"."ORDERS"."TOTAL") AS "sum", sum("PUBLIC"."ORDERS"."QUANTITY") AS "sum_2"
FROM "PUBLIC"."ORDERS"
LEFT JOIN "PUBLIC"."PRODUCTS" "Products" ON "PUBLIC"."ORDERS"."PRODUCT_ID" = "Products"."ID"
GROUP BY parsedatetime(formatdatetime("PUBLIC"."ORDERS"."CREATED_AT", 'yyyyMM'), 'yyyyMM'), "Products"."CATEGORY"
ORDER BY parsedatetime(formatdatetime("PUBLIC"."ORDERS"."CREATED_AT", 'yyyyMM'), 'yyyyMM') ASC, "Products"."CATEGORY" ASC
```
### ２．SQLでの抽出
SQLを使い慣れている人にとっては自分でクエリを作成してデータを抽出したほうがわかりやすいだろう。
GUIと同様にカテゴリ別売り上げ推移を出してみる。
左の「データについて詳しく見る」より、テーブルの列を参照できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/175aae1a-2214-3268-08ee-b237683e6296.png)

試しに書いてみると表示されるグラフが違う？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/e30ede3f-52ba-decd-ebc2-18dfa6518ae9.png)

GUIでの抽出時の表示（やクエリ）をみるとX軸の集計軸である日付が月次にまるまっていた。
GUIでの抽出ではそのあたりを可視化段階で調整できるようだ。
SQLでの抽出ではクエリで集計単位を決定する。

修正後バージョン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/efcd91a1-9971-9cba-4d95-2d950047a228.png)

## 変数の利用
SQLの経験豊富なアナリスト、データサイエンティストはGUIでの集計はあまりしないのではないだろうか。
だが上記のようにGUIでしか集計単位をグラフ上で変えられないのでは不便だ。
ダッシュボードとするなら集計単位などを変えられると便利だが、そのたびに類似のSQLをいちいち書くのも手間である。
そんな不満を解消できるのが変数の利用である。
```{{変数名}}```のように記述すると入力が可能な変数をクエリに組み込める。
```
select
    date_trunc({{date_part}},ORDERS.CREATED_AT) as term,PRODUCTS.CATEGORY,sum(ORDERS.TOTAL)
from 
    ORDERS
    join PRODUCTS on ORDERS.PRODUCT_ID = PRODUCTS.ID
group by 
    term,PRODUCTS.CATEGORY
order by term
```
上記クエリで抽出すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/09425a77-9fab-1d86-7766-ec586aaf1dd6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/46bcba08-83c6-c590-e111-fa3b1c0de129.png)
このように集計単位を簡単に変更できる。
他にも期間を絞る条件を変数で作ることもできる。
```
select
    date_trunc({{date_part}},ORDERS.CREATED_AT) as term,PRODUCTS.CATEGORY,sum(ORDERS.TOTAL)
from 
    ORDERS
    join PRODUCTS on ORDERS.PRODUCT_ID = PRODUCTS.ID
where
    1=1
    [[ and ORDERS.CREATED_AT >= {{start_day}}]]
group by 
    term,PRODUCTS.CATEGORY
order by term
```
※```[[条件式]]```とすることで必須でない条件（未入力でも実行される）を追加できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600557/0c7cf1ed-4544-7546-dd51-0802cc8ccaa7.png)


## 参考
https://zenn.dev/0yan/articles/14f0564f6abc069a8ab2