【Domo】はじめてのBeast mode①

Domo(ドーモ）は、データの接続や可視化も特別な知識がなく、直感的に操作ができるツールです。
可視化の下準備：データ整形にあたるETL処理もSQLの知識がなくても行うことができます。<br>
Domoを学び始めて、既存のデータセットからの可視化までDomoで一通りできるようになった頃、こんな場面にあったことはないでしょうか？
>・今あるデータセットの列（カラム）同士を計算させたい
・この列（カラム）さえがあれば、もっと見やすいカードが作れるのに…
・Excelだったら自分でも簡単に計算できるのに！

企業の運用によっては、可視化は許可されているがデータ作成はNG、とされているところもあるかと思います。ユーザーサイドではこんな場面もあるのではないでしょうか。<br>
>・列の追加申請が大変。。
・データセットへの列追加の対応まで時間がかかる
・カード作成の場面で必要としているので、今すぐほしい！

**こういった場面でユーザーが簡単に新たな列（カラム）を作成できるDomoの機能が、`Beast mode`です。**


`Beast mode`はSQLの記述で様々なことができる機能ですが、SQLがわからなくても、これをコピー＆ペーストすればすぐ使える！という記述をいくつかご紹介します。
※私はSQLを知らぬまま、`Beast mode`に触れ学んでいきました:door:

:::note warn 
既存のデータセットに対して、異なるデータの列追加は`Beast mode`では解決できず、データセット作成（`ETL`処理など）からの対応となる可能性が高いです。
:::
# Beast mode（ビーストモード）とは
>Beast Mode機能は、計算フィールドを追加してチャートの列を変換するのに使用できます。

引用元：[Domo Central | Beast mode計算を作成する](https://domo-support.domo.com/s/article/360043429933?language=ja)

計算して列を変換（＝追加）できる機能です。
追加された列は、カード単体でのみ使用することも、同じデータセットの他カードで使用することもできます。
使用の範囲は作成時に選択可能です（後から変更も可）<br>
この計算を行う場所へは2つのアプローチがあります。

### 1.Analyzer画面（カード作成時）
カード編集（Analyzer）画面の左下にある「計算フィールドを作成」で作成できます。
※データセットにない列を必要とする場面はカード作成時の場合が多く、私は主にこのアプローチで作成してます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/7c8959d2-1fa7-2a58-10f5-dd5d91a2320c.png" width=70%>
<br>
こちらが計算フィールドです。
作成時に、現在のカード単体で使用するか、このデータセットで共通の列として使用するか選択します。（デフォルトはカード単体）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/6749a283-c4bb-41bd-a1cb-92c1b30002f5.png" width=70%>

### 2.Beast modeマネージャー
データセットに対して列を作成します。
そのため、初めからデータセットで共通で使用する列としての作成になります。
ヘッダーの「データ」タブを選択して、左サイドのタブに”強面のおじさん"のアイコンを選びます。
※タブ→タブなので、ちょっと見つけにくいかも。。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/7ee723e9-cb01-6753-ba85-80676c2009c7.png" width=70%>
<br>
選択すると”強面のおじさん”再登場！
…彼がビースト!?※アメコミの「HELLBOY」では!?という噂も。。。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/0c905743-4c19-8cd8-e522-fef9b75d6f69.png" width=70%>
<br>
右上の「計算フィールドを作成」よりデータセットを選択したら、記述する計算フィールドが開きます。
カード作成時との違いは、列の作成を”カード単体”or”データセットで共有”の選択ができず、データセットで共有となります。（”計算をDatasetに保存”のチェックボックスが非活性）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/92760265-0bb1-2a01-5952-9c4673a20a4d.png" width=70%>_<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/af52b33c-0180-73aa-c623-871ad6e54338.png" width=70%>

:::note info
`Beast mode`が広く使われるようになると、1つのデータセットに対して似たような計算や列名だけが異なるような`Beast mode`が作成されたりもします。
そんな場面ではBeast modeマネージャーでデータセット毎や`Beast mode`に特化した管理ができます。
:::

まずはは [1.Analyzer画面（カード作成時）](#1analyzer画面カード作成時)の方法で始めてみるのがオススメです。
それでは本題のBeast modeを実際に書いてみましょう！

# 四則演算
計算って聞くと私は四則演算がまず思いつきます。Excelでも四則演算は日常的に使っている方が多いと思います。
足し算、引き算、掛け算、割り算…などの計算については、`Beast mode`での記述はExcelとほぼ同じです。
ここでは、実用場面が多い除算についてフォーカスしてみます。

#### 除算（割り算）
ここでは`前年比`（売上÷前年売上）を計算したいと思います。
使用するデータはこちらです。(本文中のデータは全てサンプルデータです)
| 日付 | 商品 | 売上 | 前年売上 |
|:-------|:-------:|-------:|-------:|
| 2024/04/01  | A | 12,000   | 8,000   |
| 2024/04/01   | B | 8,000   | 16,000   |
| 2024/04/01   | C | 12,000   | 16,000   |
| 2024/04/02  | A | 12,000  | 12,000   |
| 2024/04/02   | C | 16,000   | 8,000   |
| 2024/04/03   | C | 12,000   | 8,000   |

##### ①日別・商品別の集計
~~~markdown:Beast modeの記述
`売上` / `前年売上`
~~~
`Ａ÷Ｂ`は`Ａ/Ｂ`となり、Excelとほとんど同じですね。
結果はこのようになります。
| 日付 | 商品 | 売上 | 前年売上 | <font color="green">*前年比*</font> |
|:------- |:-------:|-------:|-------:|-------:|
| 2024/04/01  | A | 12,000   | 8,000   | <font color="green">*1.50*</font> |
| 2024/04/01   | B | 8,000   | 16,000   | <font color="green">*0.50*</font> |
| 2024/04/01   | C | 12,000   | 16,000   | <font color="green">*0.75*</font> |
| 2024/04/02  | A | 12,000  | 12,000   | <font color="green">*1.00*</font> |
| 2024/04/02   | C | 16,000   | 8,000   | <font color="green">*2.00*</font> |
| 2024/04/03   | C | 12,000   | 8,000   | <font color="green">*1.50*</font> |

新たに作成された`前年比`の列に、売上÷前年比の結果の値がありますね。
Excelで計算列を作っている感覚とほぼ同じかなと思います。

##### ②日別の集計
ただ、この記述だと行単位（今回のデータだと日別・商品別売上）で計算されているため、可視化の際の小計、合計で期待している値と異なってしまう場合があります。
日単位で集計した時の結果はこちらです。

| 日付 | 売上 | 前年売上 | *前年比* |
|:------- |:-------:|-------:|-------:|
| 2024/04/01  | 32,000   | 40,000   | <font color="red">*2.75*</font> |
| 2024/04/02   | 28,000   | 20,000   | <font color="red">*3.00*</font>  |
| 2024/04/03   | 12,000   | 8,000   | <font color="green">*1.50*</font>  |

行単位で計算した値を合計しているため、4/1と4/2の前年比がおかしな数値になってますね。
＜正しい値＞
2024/04/01　32,000÷40,000＝0.8
2024/04/02　28,000÷20,000＝1.4

Excelでいう集計行を列で集計してしまった結果と同じで、①で作成した前年比を合算している状態です。

こちらを改善するために記述を、<INS>売上を集計した後に除算</INS>となるように修正する必要があります。

~~~markdown:Beast modeの記述（修正後）
SUM(`売上`) / SUM(`前年売上`)
~~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/46b705aa-5767-fbee-4733-a0047cf6abb2.png)

結果はこのようになります。
| 日付 | 売上 | 前年売上 | *前年比* |
|:------- |:-------:|-------:|-------:|
| 2024/04/01  | 32,000   | 40,000   | <font color="green">***0.80***</font> |
| 2024/04/02   | 28,000   | 20,000   | <font color="green">***1.40***</font> |
| 2024/04/03   | 12,000   | 8,000   | <font color="green">*1.50*</font> |

今度は期待している値になってますね！
修正後の記述でも、①日別・商品別での結果は先ほどと同じになります。

##### ③商品別の集計
さらに、作成した`前年比`を使用して商品別で集計した場合の結果はこちらです。
| 商品 | 売上 | 前年売上 | *前年比* |
|:------- |:-------:|-------:|-------:|
| A | 24,000   | 20,000   | <font color="green">*1.20*</font> |
| B | 8,000   | 16,000   |  <font color="green">*0.50*</font> |
| C | 40,000   | 32,000   |  <font color="green">*1.25*</font> |

集計が日付から商品に変わっても正しい値になっていますね。


## まとめ
・`Beast mode`は、SQLの知識がなくても使い始めることができる機能です。まずは四則計算から慣れてみましょう。
・粒度が異なる集計でも柔軟に利用できる`Beast mode`を心がけましょう。

<details><summary>おまけ：Nullや0を含むデータの計算</summary>

::: note info 
### Nullや0を含むデータの計算
Beast modeで除算をした際にエラーとなってしまう場合、要因の一つに集計したい列でデータの欠損の可能性が挙げられます。
データセット作成時のETL処理での解決が望ましいですが、`Beast mode`で解決することもできます。
ここでは検証のため、新たに`前年差`（売上-前年売上）を作成します。

~~~markdown:前年差　Best modeの記述
SUM(`売上`) - SUM(`前年売上`)
~~~

## Nullを含めた計算
4/3の前年売上をNullとします。

### Nullを含む減算
| 日付 | 商品 | 売上 | 前年売上 | 前年比 |前年差 |
|:------- |:-------:|-------:|-------:|-------:|-------:|
| 2024/04/01  | A | 12,000   | 8,000   | 1.50 | *4,000*|
| 2024/04/01   | B | 8,000   | 16,000   | 0.50 |　*-8,000*|
| 2024/04/01   | C | 12,000   | 16,000   | 0.75 |*-4,000*|
| 2024/04/02  | A | 12,000  | 12,000   | 1.00 |　*0*|
| 2024/04/02   | C | 16,000   | 8,000   | 2.00 |　*8,000*|
| 2024/04/03   | C | 12,000   | <font color=red>*Null*</font>  |  <font color=red>*Null*</font> | <font color=red>*Null*</font> |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/d714212f-a26d-a2eb-c6e7-a3607bbc482c.png" width=100%>

前年比：12,000 / Null = Null
前年差：12,000 - Null = Null
`前年比`（除算）、`前年差`（減算）ともに、結果はNullになります。

<!--
| 商品 | 売上 | 前年売上 | 前年比 | 前年差|
|:------- |:-------:|-------:|-------:|-------:|
| A | 24,000   | 20,000   | *1.20* |*4,000*|
| B | 8,000   | 16,000   |  *0.50* |*-8,000*|
| C | 40,000   | <font color=red>24,000</font>   |  <font color=red>*1.66…*</font>  |<font color=red>*16,000*</font> |

![スクリーンショット 2024-11-17 173253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/80fa47e8-5cce-c345-8d91-d01c016b8af7.png)

集計はNullを除いて正しく行われました。
`前年差`も集計後の減算となるため、正しい値になっています。
-->

## 0を含めた計算
4/3の前年売上＝0とします。

### 分母が0の除算
| 日付 | 商品 | 売上 | 前年売上 | 前年比 | *前年差* |
|:------- |:-------:|-------:|-------:|-------:|-------:|
| 2024/04/01  | A | 12,000   | 8,000   | *1.50* | *4,000*|
| 2024/04/01   | B | 8,000   | 16,000   | *0.50* |　*-8,000*|
| 2024/04/01   | C | 12,000   | 16,000   | *0.75* |　*-4,000*|
| 2024/04/02  | A | 12,000  | 12,000   | *1.00* |　*0*|
| 2024/04/02   | C | 16,000   | 8,000   | *2.00* |　*8,000*|
| 2024/04/03   | C | 12,000   | <font color=red>*0*</font>  | <font color=red>*Null*</font> | *12,000*|

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/bbc097cd-98b7-074c-d875-1cc71d62cc9b.png" width=100%>

前年比：12,000 / 0 = Null
前年差：12,000 - 0 = 12,000
今回、Beast modeの除算では分母＝０の場合にNullとなりましたが、エラーとなる可能性が高い計算です。

<!--
### 集計後の除算
C売上合計：40,000(=12,000+16,000+12,000）
C前年売上合計:24,000 (=16,000+8,000+0）
C前年比：40,000 / 24,000 = 1.66…
| 商品 | 売上 | 前年売上 | 前年比 | *前年差*|
|:------- |:-------:|-------:|-------:|-------:|
| A | 24,000   | 20,000   | *1.20* |*4,000*|
| B | 8,000   | 16,000   |  *0.50* |*-8,000*|
| C | 40,000   | <font color=red>24,000</font>   |  <font color=red>*1.66…*</font>  |<font color=red>*16,000*</font> |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936844/537678ee-0492-77f5-1a1f-a4320ef9609f.png" width=100%>

集計（SUM）は正しく行われます。
-->

## Nullを含む列でのBeast mode
値がNullの場合、減算で正しく計算されるように、Nullを0に置き換えます。
置き換えには`IFNULL`を使用します。
`IFNULL`単体での記述だと、以下のような結果になります。

~~~markdown:Best modeの記述
IFNULL(`前年売上`,0)
~~~

| 日付 | 商品 | 売上 | 前年売上 |
| ------- | ------- | ------- | ------- |
| 2024/04/01  | A | 12,000   | 8,000   |
| 2024/04/01   | B | 8,000   | 16,000   |
| 2024/04/01   | C | 12,000   | 16,000   |
| 2024/04/02  | A | 12,000  | 12,000   |
| 2024/04/02   | C | 16,000   | 8,000   |
| 2024/04/03   | C | 12,000   | 0  |

これを一つの記述にまとめると以下のようになります。

~~~markdown:前年差（修正後）Best modeの記述
SUM(IFNULL(`売上`,0) - SUM(IFNULL(`前年売上`,0))
~~~

## 0を含む列でのBeast mode
今回の結果はNullでしたが、一般的にSQLでは除算時の分母が0の場合にエラーとなります。
エラーを回避するため、0をNullに置き換えするため、`NULLIF`を使用します。
`NULLIF`単体での記述は以下になります。

~~~markdown:Best modeの記述
NULLIF(`前年売上`,0)
~~~
このまま使用すると、Nullを含む集計になってしまうため以下のようにします。

~~~markdown:前年比（修正後）Best modeの記述
SUM(`売上`,0) / NULLIF（SUM(`前年売上`),0)
~~~

これで`前年売上`の集計結果が0の場合、Nullに置き換えてから除算してエラーを回避できます。

## まとめ
・予期せぬエラーを未然に回避するため、四則演算の際は`IFNULL`、`NULLIF`を用途に合わせて使い分けましょう。
・データセット作成時のETL処理でNullや0を適切な値にすると、カード作成時の`Beast mode`の記述の負担が減ります。できるだけETLでの処理を心がけましょう。

</details>