次の方法で共有


変数を使用して DAX 数式を改善する

データ モデリングツールとして、いくつかの DAX 計算の記述とデバッグは困難な場合があります。 複雑な計算要件には、多くの場合、複合式または複雑な式の記述が含まれることがよくあります。 複合式では、多くの入れ子になった関数を使用したり、場合によっては式ロジックを再利用したりできます。

DAX 数式で変数を使用すると、より複雑で効率的な計算を記述できます。 変数を使用すると、パフォーマンス、信頼性、読みやすさを向上させ、複雑さを軽減できます。

この記事では、前年比(YoY)の売上成長を例にした指標を使用して、最初の3つの利点を示します。 (YoY 売上の伸びの数式は、期間の売上から前年の同じ期間の売上を差し引いた後、その値を前年の同じ期間の売上で割ったものです。)

次の指標定義から始めましょう。

Sales YoY Growth % =
DIVIDE(
    ([Sales] - CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))),
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
)

指標は正しい結果を生成しますが、しかし、さらに改善できるか見てみましょう。

パフォーマンスの向上

数式は、"昨年同じ期間" を計算する式を繰り返していることに注意してください。 この数式は、Power BI で同じ式を 2 回評価する必要があるため、非効率的です。 変数 VARを使用することで、メジャー定義をより効率的にすることができます。

次の指標の定義は改善を示しています。 式を使用して、「昨年同じ期間」の結果を SalesPriorYearという名前の変数に割り当てます。 その後、変数は RETURN 式で 2 回使用されます。

Sales YoY Growth % =
VAR SalesPriorYear =
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
RETURN
    DIVIDE(([Sales] - SalesPriorYear), SalesPriorYear)

この対策は引き続き正しい結果を生み出し、クエリの時間が約半分でそれを実現します。

読みやすさの向上

前のメジャー定義では、変数名を選択すると RETURN 式が理解しやすくなります。 式は短く、自己記述型です。

デバッグを簡略化する

変数は、数式のデバッグにも役立ちます。 変数に割り当てられた式をテストするには、RETURN 式を一時的に書き換えて変数を出力します。

次のメジャー定義は、SalesPriorYear 変数のみを返します。 対象の RETURN 式がどのようにコメントアウトされているかに注目してください。 この手法を使用すると、デバッグが完了したら簡単に元に戻すことができます。

Sales YoY Growth % =
VAR SalesPriorYear =
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
RETURN
    --DIVIDE(([Sales] - SalesPriorYear), SalesPriorYear)
    SalesPriorYear

複雑さを軽減する

以前のバージョンの DAXでは、変数はまだサポートされていませんでした。 EARLIER または EARLIESTDAX 関数を使用して外部フィルター コンテキストを参照するには、新しいフィルター コンテキストを導入する複雑な式が必要でした。 残念ながら、データ モデラーは、これらの関数を理解して使用するのが難しいことがわかりました。

変数は常に、RETURN 式が適用するフィルターの外側で評価されます。 このため、変更されたフィルター コンテキスト内で変数を使用すると、EARLIEST 関数と同じ結果が得られます。 したがって、EARLIER または EARLIEST 関数の使用は避けることができます。 これは、複雑でなく、理解しやすい数式を記述できるようになったことを意味します。

Subcategory テーブルに追加された次の計算列定義について考えてみます。 Subcategory Sales 列の値に基づいて、各製品サブカテゴリのランクを評価します。

Subcategory Sales Rank =
COUNTROWS(
    FILTER(
        Subcategory,
        EARLIER(Subcategory[Subcategory Sales]) < Subcategory[Subcategory Sales]
    )
) + 1

EARLIER 関数は、「サブカテゴリ売上」 列の値 を現在の行コンテキストで参照するために使用されます。

計算列の定義は、EARLIER 関数の代わりに変数を使用することで改善できます。 CurrentSubcategorySales 変数は、現在の行コンテキストに Subcategory Sales 列の値を格納し、RETURN 式は変更されたフィルター コンテキスト内でそれを使用します。

Subcategory Sales Rank =
VAR CurrentSubcategorySales = Subcategory[Subcategory Sales]
RETURN
    COUNTROWS(
        FILTER(
            Subcategory,
            CurrentSubcategorySales < Subcategory[Subcategory Sales]
        )
    ) + 1