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