Power BI 勉強会 #21 で話したこと - 日付テーブルとは！ 

日付テーブルについてお話ししようと思うのだ。

# ふわっとまとめ

- **Auto date/time は OFF にしておいたほうがよいぜ**
- **日付テーブルには ALL('日付テーブル') っていう、CALCULATE modifier が適用されているのだぜ**

自動で設定してくれる機能や実現するためのローコードが存在するとき、それらを勉強しなくてもよいということではない。以降において、それらを理解していることが望ましく、少なくとも知っていることが前提になっているということだ。
# 知っておくべきこと
## Auto date/time
自動で 日付テーブルを生成したり更新する機能があるけれども、必要な機能ですか？という自問自答をしてみてはどうだろうか。

https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-auto-date-time

### おすすめ設定 Power BI Desktop
デフォルトの設定では、日付テーブルを生成する機能が ON である。ただ、想像するより便利な機能ではないから Global では "OFF" にしておくとよい。
[Options] - [GLOBAL] - [Data Load] - [Time intelligence] - [Aute date/time for new file] : OFF

で、必要な時だけ ON にしておくほうがスマートだ。

[Options] - [CURRENT FILE] - [Data Load] - [Time intelligence] - [Aute date/time]

### なぜか
そもそも使いたいなと思うことがないのだけど、合理的と思える理由を挙げる。

- 生成された日付テーブルに列の追加や、フォーマットを変更することができない。
- データモデルに含まれる多くの日付列ごとに、日付テーブルが作成されることがある。
- Analyze in Excel では表示されない日付テーブルになり、期待する結果を得られないことがある。
- 勉強を邪魔する。うざい(心の叫び)

それでも使いたいのなら、この機能が ON であるときどのようなことが起きているのか。どのような結果を得ることができるのかをよーく理解しておくべきだ。この機能を理解していて利用に値する機会であるならば ON にすべきだ。ただ、この先深く勉強しなければならないとき、こんなことがきっかけでつまずくのはもったいなさすぎるのだ。


## 日付テーブルとしてマークする
タイム インテリジェンス 関数 を使う集計を行うとき、日付テーブルは必須である。このとき、タイム インテリジェンス 関数が十分に機能するかどうか、適切なテーブルとデータになっているかの検査も実施してくれる機能だ。なので、必ず利用する。では、どのような機能なのか。

### 実施される検証
タイム インテリジェンス 関数で指定する引数は 日付(日付時刻)列 なので、要件を満たす日付列になっているか検証が行われる。

- 日付（日付時刻)列の存在
- 日付列値の重複もしくはギャップ
- 日付列に時刻情報がないこと( AM 12:00:00 のみ許容 )

### 追加される機能
タイム インテリジェンス 関数による集計が期待通りに行われることがほぼ保障されること。"ほぼ"というのは、日付テーブルのデータに問題があるときは別であるから。

https://qiita.com/PowerBIxyz/items/924893764e6fdce30f92

上記重要なこと以外だと、クイック メジャーによるタイム インテリジェンス 集計がちょっと使えるようになるかもね。

### 行われる内部の動作
テーブルと列のプロパティ変更が行われる。Power BI Desktop の作業では、ここまで意識する必要はないけれども。

- テーブルのプロパティ : Data Category = 2(Time)
- 日付列のプロパティ : Key = True

データセット更新するとき不運にも日付列に重複が発生したとき、 列の Key プロパティにより更新が失敗に終わるのだ。

## 日付テーブルの特有の動作
いろんな方のモデルや記述されたメジャーを見ていると、日付テーブル特有の動作を理解していないのでは？と思うことが多いのだ。

日付テーブルはスタースキーマでいうところのディメンジョンテーブルの一種なわけだが、定義されるデータは日付であり、どのデータモデルでも同じ使われ方なのである。なので、日付テーブルに関しては特有の動作をしていて便利なはずの機能なのだ。
特有の動作は、

- 日付テーブルとしてマークされている
- 日付列 ( 1 : 多 ) 日付列 のリレーションシップが設定されている

のいづれかで発動する。
### 特有の動作とは
日付テーブル : Dates としたとき、常に ALL( Dates ) もしくは REMOVEFILTERS( Dates ) が暗黙的に適用されるのである。

```text:メジャー
Sales amount =
SUMX( Sales, Sales[Unit price] * Sales[Quantity] )
```

```text:メジャー
Sales amount (Cumulative) =
VAR MaxDate = MAX( Dates[Date] )
VAR Result =
    CALCULATE(
        [Sales Amount],
        Dates[Date] <= MaxDate
    )
RETURN
    Result
```

このとき、

```text:DAXクエリ
EVALUATE
SUMMARIZECOLUMNS(
    Dates[Year], Dates[Month],
    "Sales amount (Cumulative)", [Sales amount (Cumulative)]
)
ORDER BY Dates[Year], Dates[Month]
```

が期待する結果で集計されるのだ。

```text:メジャー
Sales amount (Cumulative) =
VAR MaxDate = MAX( Dates[Date] )
VAR Result =
    CALCULATE(
        [Sales Amount],
        Dates[Date] <= MaxDate,
        // ALL( Dates ) REMOVEFILTERS( Dates ) 👈暗黙的に適用されている
    )
RETURN
    Result
```

CALCULATE の *filter* 引数 は、依然としてベストプラクティス通り 列フィルタで記述できるのだ。
*filter* 引数に利用する ALL*関数は、 CALCULATE modifier ってことにも理解が必要。

# 思ったこと🙄
記述されたメジャーを見ると、あぁ勉強足りなくね？とか、間違った勉強しちゃってんじゃね？と思うのである。
# その他
https://powerbi.connpass.com/

http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981

http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9

- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)