その他のタイム インテリジェンス計算
1 つの日付を返すその他の DAX タイム インテリジェンス関数があります。 これらの関数を、2 つの異なるシナリオで適用することによって説明していきます。
FIRSTDATE
および LASTDATE
DAX 関数を使用すると、指定した日付列について、現在のフィルター コンテキストでの最初と最後の日付が返されます。
新規の発生回数を計算する
タイム インテリジェンス関数のもう 1 つの用途は、新規の発生回数をカウントすることです。 次の例は、ある期間における新規顧客の数を計算する方法を示しています。 新規顧客の数は、その顧客が初めて購入した期間でカウントされます。
最初のタスクは、一意な顧客の "期間累計" (LTD) 数をカウントする次のメジャーを Sales テーブルに追加することです。 期間累計は、期間の始めからフィルター コンテキストの最後の日付までを意味します。 桁区切り記号を使用して、メジャーを整数値として書式設定します。
Customers LTD =
VAR CustomersLTD =
CALCULATE(
DISTINCTCOUNT(Sales[CustomerKey]),
DATESBETWEEN(
'Date'[Date],
BLANK(),
MAX('Date'[Date])
),
'Sales Order'[Channel] = "Internet"
)
RETURN
CustomersLTD
行列の視覚エフェクトに Customers LTD メジャーを追加します。 各月の終わりまでの、一意な顧客の LTD の結果が生成されることがわかります。
DATESBETWEEN
関数 - 指定した開始日で始まり、指定した終了日まで続く日付の列を含むテーブルが返されます。 開始日が空白の場合は、日付列の最初の日付が使用されます。 (逆に、終了日が空白の場合は、日付列の最後の日付が使用されます。)このケースの場合、終了日は MAX 関数によって決定され、フィルター コンテキストの最後の日付が返されます。 したがって、2017 年 8 月の月がフィルター コンテキストである場合、MAX 関数によって 2017 年 8 月 31 日が返され、DATESBETWEEN
関数によって 2017 の 8 月 31 日までのすべての日付が返されます。
次に、このメジャーを変更します。名前を New Customers に変更し、フィルター コンテキストの期間 "以前の" 一意な顧客の数を格納する 2 つ目の変数を追加します。 RETURN
句では、この値を LTD 顧客数から減算して結果を生成しています。これは期間内の新規顧客の数になります。
New Customers =
VAR CustomersLTD =
CALCULATE(
DISTINCTCOUNT(Sales[CustomerKey]),
DATESBETWEEN(
'Date'[Date],
BLANK(),
MAX('Date'[Date])
),
'Sales Order'[Channel] = "Internet"
)
VAR CustomersPrior =
CALCULATE(
DISTINCTCOUNT(Sales[CustomerKey]),
DATESBETWEEN(
'Date'[Date],
BLANK(),
MIN('Date'[Date]) - 1
),
'Sales Order'[Channel] = "Internet"
)
RETURN
CustomersLTD - CustomersPrior
CustomersPrior 変数において、DATESBETWEEN
関数に含まれる日付が、フィルター コンテキストの最初の日付から 1 を "引いた" 日付までになっていることに注目します。 Microsoft Power BI の内部では日付が数値として格納されるため、数値を加算または減算して日付をシフトすることができます。
スナップショット計算
場合によっては、ファクト データが期間内のスナップショットとして格納されることがあります。 一般的な例としては、在庫レベルや口座残高などがあります。 値のスナップショットは、定期的にテーブルに読み込まれます。
スナップショット値 (在庫レベルなど) を集計する場合、日付を除く任意のディメンションにわたる値を集計できます。 商品カテゴリにわたる在庫レベルの数を加算する場合は意味のある概要を作成できますが、日付にわたる在庫レベルの数を加算する場合はそうではありません。 昨日の在庫レベルを今日の在庫レベルに加算する操作を実行しても、役に立ちません (結果を平均する必要がある場合を除く)。
スナップショット テーブルを集計する場合、メジャーの数式で DAX タイム インテリジェンス関数を使用して、単一の日付フィルターを適用することができます。
次の例では、Adventure Works 社のシナリオについて調べます。 モデル ビューに切り替えて、Inventory モデル ダイアグラムを選択します。
この図には 3 つのテーブル、Product、Date、Inventory が表示されていることがわかります。 Inventory テーブルには、日付と製品ごとのユニット残高のスナップショットが格納されます。 テーブルには、不足している日付がなく、どの製品についても同じ日付の重複するエントリが含まれていないことが重要です。 また、最後のスナップショット レコードは 2020 年 6 月 15 日の日付に対して格納されています。
次に、レポート ビューに切り替えて、レポートのページ 2 を選択します。 行列のビジュアルに、Inventory テーブルの UnitsBalance 列を追加します。 その既定の概要作成は合計値に設定されます。
この視覚エフェクトの構成は、スナップショットの値を集計しない方法の例です。 毎日のスナップショットの残高を加算しても、意味のある結果は得られません。 そのため、行列の視覚エフェクトから UnitsBalance フィールドを削除します。
ここで、Inventory テーブルに 1 日分の UnitsBalance 値を合計するメジャーを追加します。 日付は、各期間の最後の日付になります。 これは、LASTDATE
関数を使用して実現されます。 桁区切り記号を使用してメジャーを整数値として書式設定します。
Stock on Hand =
CALCULATE(
SUM(Inventory[UnitsBalance]),
LASTDATE('Date'[Date])
)
Note
このメジャーの数式では、SUM
関数が使用されていることに注目します。 集計関数を使用する必要があります (メジャーで列を直接参照することはできません)。ただし、各日付の各製品に 1 つの行のみが存在している場合、SUM
関数は 1 つの行に対してのみ機能します。
行列の視覚エフェクトに Stock on Hand メジャーを追加します。 各製品の値は、毎月の最後に記録されたユニット残高に基づいています。
このメジャーは、2020 年 6 月に対して空白を返します。6 月の最後の日付のレコードが存在しないためです。 データによれば、それはまだ発生していません。
フィルター コンテキストの最後の日付によるフィルター処理には、固有の問題があります。まだ発生していなかったり、週末に在庫残高が記録されなかったりすることが原因で、記録された日付が存在しない可能性があります。
次の手順は、"空白以外の結果を含む" 最後の日付を特定し、その日付でフィルター処理するように、メジャーの数式を調整することです。 このタスクを実現するには、LASTNONBLANK
DAX 関数を使用します。
次のメジャー定義を使用して、Stock on Hand メジャーを変更します。
Stock on Hand =
CALCULATE(
SUM(Inventory[UnitsBalance]),
LASTNONBLANK(
'Date'[Date],
CALCULATE(SUM(Inventory[UnitsBalance]))
)
)
行列の視覚エフェクトに、2020 年 6 月と合計 (年度全体を表す) の値が表示されています。
LASTNONBLANK
関数は反復子関数です。 空白以外の結果を生成する最後の日付が返されます。 この結果は、フィルター コンテキストのすべての日付を、"降順の時系列順" で反復処理することによって実現されます。 (逆に、FIRSTNONBLANK
では昇順の時系列順で反復処理されます。) 日付ごとに、渡された式が評価されます。 空白以外の結果が検出されたとき、関数からその日付が返されます。 次に、その日付を使用して CALCULATE
関数をフィルター処理します。
注意
LASTNONBLANK
関数を使用すると、行コンテキストでその式が評価されます。 行コンテキストをフィルター コンテキストに切り替えて式を正しく評価するために、CALCULATE
関数を使用する必要があります。
ここで、Inventory テーブルの UnitsBalance 列を非表示にする必要があります。 これにより、レポート作成者がスナップショット ユニット残高を不適切に集計できなくなります。
ヘルプが必要ですか? Microsoft のトラブルシューティング ガイドをご覧になるか、問題を報告して具体的なフィードバックをお送りください。