[Power BI] DAXの 計算列 vs メジャー

　計算列もメジャーもDAX式を使用しているため、最初はその違いが理解できないのですが、非常に異なる方法で計算を行っています。違いと使い方を説明します。

# 計算列 (Calculated Columns) の特徴
- 計算列は、Excelのように、行ごとの列と列を計算して新しい列を作成し、計算結果はテーブル内に格納されます。
- 計算列はテーブル内の行ごとで計算されます。行をまたがった計算はできません。
- 再計算されるのは、更新を押した時だけなので、フィルターコンテキストで動的に変化する値を持たせることはできません。
- フィルターやスライサー、リレーションシップに使用できます。

# メジャー (Measure) の特徴
- モデル内にDAX式として保存され、値は保存されずフィルターコンテキストで動的に計算されます。
- テーブル内の行に縛られず、列ベースの計算に使用できます。
- テーブルに紐づいていないため、テーブル間の計算も行えます。
- フィルターやスライサー、リレーションシップに使用できません。

# ファイルサイズの増加
　計算列は、計算結果の値をモデル内に持ち、メジャーは値ではなく式だけを持つということを確認してみます。
　以下のような7,000件のデータがPower BI Desktopにあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7e724769-16a9-410e-2f3a-0e31bdd1bea5.png)
　このpbixファイルサイズは、83,763バイトでした。

　Gross Sales, Sales, Profitの3つの列を追加しました。

```
Gross Sales = [Units Sold] * [Sale Price]
Sales = [Gross Sales] - [Discounts]
Profit = [Sales] - [COGS]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3b314c6f-c5db-0bb5-8fba-d8db7de18e97.png)
　ファイルサイズは、103,788バイトと、約24％増加しました。

　次に、上記の3列をメジャーを使って追加してみました。メジャーは計算列と異なり、計算はまだ行われておらず、値がメモリ上にないため、Power BI Desktopの左側にある「データ」タブから表示させることはできません。レポート上でビジュアルに配置することで計算が行われ、表示できます。

```
Gross Sales = SUMX(financials, financials[Units Sold] * financials[Sale Price])
Sales = SUMX(financials, [Gross Sales] - financials[Discounts])
Profit = SUMX(financials, [Sales] - financials[COGS])
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/43a526f4-bdd1-b6bd-5044-602ba66d577a.png)

　ファイルサイズは、84,241バイトと、約0.6％の微増となりました。

　データは、できるだけ小さいサイズになるよう圧縮され、保存されます。

# 列ベースの計算（タイムインテリジェンス）
 メジャーでは、行をまたがる計算、タイムインテリジェンスを使用した計算ができます。例えば、年累計は複雑な計算を行うことなく、メジャーで書くことができます。

```
年累計 = TOTALYTD([Profit], '日付テーブル'[Date], "3/31")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c4e705a9-b53d-6920-0de6-eb9b178b15b8.png)
　この１つのメジャーを書くだけで、各種フィルターを使って分析することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/100fdda4-c1b7-5e29-0cc7-506ec7f29d3f.png)
　これをメジャーを使わずに計算列で行うことは難しいでしょう。

# 計算列とメジャーの使いどころ
　計算列は、大規模なトランザクションをチェックするための項目などの最終的な結果を得るための中間ステップとしてよく使用されます。

　AOV (平均注文値) や ROI (投資収益率) などの比率を計算する場合は、メジャーを作成する必要があります。このような場合に計算列を使用すると、間違った結果が得られます。
 ビジュアルで表示させる数値の項目は、原則メジャーにしておくことが望ましいです。また、途中結果を確認しながら計算を行いたい場合は、変数を使いうことでデバッグを行うことができます。

```
Age Group Sort =
var age = rounddown((date(2018,1,1) - Customers[BirthDate])/365, 0)
return
    CALCULATE(
        VALUES(AgeBands[Band]),
        FILTER(AgeBands,
            age >= AgeBands[Low] && age < AgeBands[Heigh]
        )
    )
```

https://qiita.com/spumoni/items/82a1e4ebc36e00086e66

# 書き方の違い
　メジャーと計算列では、計算対象が異なるため、書き方にも違いがあります。

　以下のようなテーブルで金額を計算する場合、計算列では以下のように書きます。

```
金額 = 'テーブル'[個数] * 'テーブル'[単価]
```
　テーブルビューには以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a3bfbee9-a61c-d6fe-ef91-cefd50539685.png)

　一方、メジャーで書く場合は以下のようにしないと正しい値になりません。

```
金額 = SUMX('テーブル', 'テーブル'[個数] * 'テーブル'[単価])
```

　メジャーで作成した場合は値がテーブルに保存されないため、テーブルビューで表示させることはできませんが、ビジュアルで表示させると、いずれも以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/46120d4b-303f-feff-170d-d6f1e838cb0a.png)
　しかし、種別で集計を行う場合、メジャーと計算列の動きは変わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1213ffef-c5c7-dd40-e7ad-54709c22c917.png)
　種別の合計を求めるには、列の集計方法「合計」にしてやる必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/d49b0bf5-cbd0-54d7-73bc-485304594a26.png)
　メジャーで正しい値を得るためには、フィルターコンテキストなどのメジャーの特性を理解しなければなりません。

# 計算列を使用したほうが良いと思える例
　静的セグメンテーションとABC分類では、計算列を使用したほうがよいでしょう。
　この2つの例では、値をグループ化して分析を行います。
　
# 視覚化する前にやること
- 分析したいデータの項目がきちんとそろっているか。
    - 他のデータソースが必要か。
    - 項目の作成方法は、Power Query、計算列、メジャーのどれを使うか
    - 項目の目的を考える。
        - 動的な値として使用しない場合は、ソース側、Power Query、計算列の順番で、できるだけ早い段階で項目を作成しておく。
        - フィルター、スライサーに使用する場合は、メジャーを使わない。
        - 数値項目は可能な限りメジャーを使用する。
        - タイムインテリジェンスを使用して集計する項目はメジャーを使用する。
- 各項目のデータがエラーやブランクがなくきれいになっているか。
- 日付の項目に時間が入っていないか。
    - 日付項目と時間項目を分けておくとデータの圧縮効率がよい。
    - タイムインテリジェンスを使うためには日付のみの項目が必要。
- 日付テーブルが作ってあるか。
- 分析に使用するディメンションテーブルが作ってあるか。
    - 作り方はPower Queryを使ったり、VALUESやDISTINCTを使って新しいテーブルを作る。
- ディメンションテーブルにした項目や、日付、直接分析に使用しない項目は非表示にしてあるか。