mcpField
D
dax-mastery

dax-mastery

github.com/josiahsiegelデータ・データベース5997 回インストール19 週間前に更新
リポジトリ

dax-mastery について

Power BI のモデル作成者向け DAX リファレンスです。評価コンテキスト、計算、時間インテリジェンス、イテレーター、パフォーマンスのパターンを解説し、計算グループや新しい言語機能も扱います。

主な機能

  1. 01行コンテキストとフィルターコンテキスト
  2. 02CALCULATE のフィルター動作
  3. 03時間インテリジェンス関数とパターン
  4. 04イテレーター関数とテーブル関数
  5. 05計算グループとフィールドパラメーター
  6. 06ウィンドウ計算とビジュアル計算

活用シーン

  1. 01メジャーと計算列の作成
  2. 02前年比やローリング期間の分析
  3. 03DAX 式のパフォーマンス改善
  4. 04モデル内で計算パターンを再利用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill dax-mastery

インストール後、Claude Code で/dax-masteryを入力して読み込まれたか確認します。

同梱ファイルreferences/dax-function-categories.mdreferences/dax-patterns-advanced.md

詳細

DAX(Data Analysis Expressions)を極める

概要

評価コンテキスト、CALCULATE、時系列分析、イテレーター、テーブル関数、パフォーマンス最適化、高度なパターンを網羅したDAXリファレンスです。DAXは、Power BIのメジャー、計算列、計算テーブル、RLSフィルターに使用する数式言語です。

評価コンテキスト

行コンテキスト
  • 作成される場面:計算列、イテレーター(SUMX、FILTER、AVERAGEXなど)、行ごとの評価
  • テーブルの各行には、それぞれ独自の行コンテキストがあります
  • 列には直接アクセスします:Sales[Amount]
  • イテレーターをネストすると、行コンテキストもネストされます
フィルターコンテキスト
  • 作成される場面:スライサー、ビジュアルフィルター、ページフィルター、レポートフィルター、CALCULATEの引数
  • 集計関数に表示される行を決定します
  • 行レベルのアクセスはできません(集計せずにメジャー内で Sales[Amount] を直接使用することはできません)
コンテキスト遷移
  • CALCULATEは行コンテキストをフィルターコンテキストに変換します
  • イテレーター内でメジャーを参照すると発生します
  • 各行の列値がフィルター引数になります
// Context transition example:
Sales Amount = SUM(Sales[Amount])

// Inside SUMX, each row triggers context transition:
Weighted Amount =
SUMX(
    Products,
    Products[Weight] * [Sales Amount]  // [Sales Amount] triggers CALCULATE internally
)

CALCULATE - 最も重要な関数

CALCULATE(<expression>, <filter1>, <filter2>, ...)

フィルター引数の種類:

種類例動作
ブール値(テーブルフィルター)Products[Color] = "Red"フィルターを追加し、既存のコンテキストを維持します
テーブル式FILTER(ALL(Products), Products[Price] > 100)対象列のフィルターを置き換えます
REMOVEFILTERSREMOVEFILTERS(Products[Color])列の既存のフィルターを削除します
ALLALL(Products)テーブルのすべてのフィルターを削除します
KEEPFILTERSKEEPFILTERS(Products[Color] = "Red")既存のフィルターと交差させます
USERELATIONSHIPUSERELATIONSHIP(Sales[ShipDate], Date[Date])非アクティブなリレーションシップを有効にします
CROSSFILTERCROSSFILTER(Sales[ProductID], Products[ID], Both)クロスフィルターの方向を変更します

重要なルール:

  • ブール値フィルターは、FILTER(ALL(column), condition)の構文糖衣です
  • ブール値フィルターは、その列の既存のフィルターを置き換えます
  • 既存のフィルターに追加(交差)するには、KEEPFILTERSを使用します
  • CALCULATEの修飾子(ALL、REMOVEFILTERS)はフィルター引数より先に実行されます

時系列分析クイックリファレンス

前提条件: 連続した日付列を持ち、日付テーブルとしてマークされた適切な日付テーブルが必要です。

関数用途例
TOTALYTD年初来TOTALYTD([Sales], Date[Date])
TOTALMTD月初来TOTALMTD([Sales], Date[Date])
TOTALQTD四半期初来TOTALQTD([Sales], Date[Date])
SAMEPERIODLASTYEAR前年の同一期間CALCULATE([Sales], SAMEPERIODLASTYEAR(Date[Date]))
DATEADD指定した間隔だけ移動CALCULATE([Sales], DATEADD(Date[Date], -1, MONTH))
PARALLELPERIOD移動後の期間全体CALCULATE([Sales], PARALLELPERIOD(Date[Date], -1, QUARTER))
DATESYTD年初来に絞り込んだ日付テーブルCALCULATE([Sales], DATESYTD(Date[Date]))
DATESBETWEEN日付範囲CALCULATE([Sales], DATESBETWEEN(Date[Date], start, end))
PREVIOUSMONTH前月全体CALCULATE([Sales], PREVIOUSMONTH(Date[Date]))
PREVIOUSYEAR前年全体CALCULATE([Sales], PREVIOUSYEAR(Date[Date]))

よく使われる時系列分析パターン:

// Year-over-Year Growth %
YoY Growth % =
VAR CurrentSales = [Total Sales]
VAR PriorYearSales = CALCULATE([Total Sales], SAMEPERIODLASTYEAR(Date[Date]))
RETURN
    DIVIDE(CurrentSales - PriorYearSales, PriorYearSales)

// Rolling 12-Month Total
Rolling 12M =
CALCULATE(
    [Total Sales],
    DATESINPERIOD(Date[Date], MAX(Date[Date]), -12, MONTH)
)

// Moving Average (3 months)
3M Moving Avg =
AVERAGEX(
    DATESINPERIOD(Date[Date], MAX(Date[Date]), -3, MONTH),
    CALCULATE([Total Sales])
)

変数(VAR/RETURN)

読みやすさとパフォーマンスのため、常に変数を使用します:

Profit Margin % =
VAR TotalRevenue = SUM(Sales[Revenue])
VAR TotalCost = SUM(Sales[Cost])
VAR Profit = TotalRevenue - TotalCost
RETURN
    DIVIDE(Profit, TotalRevenue)

ルール:

  • 変数は一度だけ評価されます(再利用時にパフォーマンス上の利点があります)
  • 変数は定義時点のフィルターコンテキストを保持します
  • 変数にはスカラー値またはテーブルを格納できます
  • 意味のある名前を使用します(x、tempは避けてください)

イテレーター関数

イテレーターはテーブルを行ごとにスキャンし、行コンテキストを作成します。

関数目的
SUMX行ごとに評価した式の合計
AVERAGEX行ごとに評価した式の平均
MINX / MAXX行ごとに評価した式の最小値/最大値
COUNTX空白でない式の結果の数
RANKX式に基づく順位
FILTER条件に一致するテーブル行を返します
ADDCOLUMNSテーブルに計算列を追加します
SELECTCOLUMNS選択した列または計算列を含むテーブルを返します
GENERATE行コンテキストを使ったクロス結合
// Weighted average price
Weighted Avg Price =
SUMX(
    Sales,
    Sales[Quantity] * RELATED(Products[UnitPrice])
) / SUM(Sales[Quantity])

計算グループ

再利用可能な計算パターンを定義して、メジャーの増加を抑えます。

// Instead of creating YTD, PY, YoY for EVERY measure:
// Create ONE calculation group with items:
// - Current: SELECTEDMEASURE()
// - YTD: CALCULATE(SELECTEDMEASURE(), DATESYTD(Date[Date]))
// - PY: CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR(Date[Date]))
// - YoY%: VAR Curr = SELECTEDMEASURE()
//         VAR PY = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR(Date[Date]))
//         RETURN DIVIDE(Curr - PY, PY)

Tabular Editor、Desktop の TMDL ビュー、または TOM/.NET SDK を使って作成します。

フィールドパラメーター

ビジュアル内でディメンションやメジャーを動的に切り替えられるようにします。

// Created via Modeling tab > New parameter > Fields
// Generates a calculated table:
Parameter =
{
    ("Revenue", NAMEOF(Sales[Total Revenue]), 0),
    ("Profit", NAMEOF(Sales[Total Profit]), 1),
    ("Units", NAMEOF(Sales[Total Units]), 2)
}

ユーザー定義関数(2025 年 9 月プレビュー)

変数(2015 年)以来、最も重要な DAX 言語の更新です。再利用可能なパラメーター付き関数を定義できます。

// Define a UDF in DAX query view or model
DEFINE
FUNCTION AddTax = (amount : NUMERIC) => amount * 1.1

// Nest UDFs
FUNCTION AddTaxAndDiscount = (amount : NUMERIC, discount : NUMERIC) =>
    AddTax(amount - discount)

EVALUATE { AddTaxAndDiscount(100, 20) }  // Returns 88

パラメーターの型: NUMERIC、Scalar、Table、AnyVal、AnyRef、CalendarRef、ColumnRef、MeasureRef、TableRef

パラメーターのモード: val(先行評価)または expr(遅延評価/コンテキスト依存)

使用方法: モデルで定義して保存すると、メジャー、計算列、ビジュアル計算、その他の UDF から UDF を呼び出せます。

有効化: File > Options > Preview features > DAX user-defined functions

ウィンドウ関数(WINDOW、INDEX、OFFSET)

行相対および範囲計算のための DAX ウィンドウ関数です。

// Running total using WINDOW
Running Total =
CALCULATE(
    [Total Sales],
    WINDOW(1, ABS, 0, REL, ALLSELECTED(Date[Month]),
        ORDERBY(Date[MonthNumber], ASC))
)

// Previous row value using OFFSET
Previous Month Sales =
CALCULATE(
    [Total Sales],
    OFFSET(-1, ALLSELECTED(Date[Month]),
        ORDERBY(Date[MonthNumber], ASC))
)

// Nth row using INDEX
First Month Sales =
CALCULATE(
    [Total Sales],
    INDEX(1, ALLSELECTED(Date[Month]),
        ORDERBY(Date[MonthNumber], ASC))
)

主な句:

  • ORDERBY -- ウィンドウ内の並べ替え順序
  • PARTITIONBY -- 行のサブセット(「ウィンドウ」のパーティション)
  • MATCHBY -- 曖昧なコンテキストで現在の行を特定します

ビジュアル計算(2024~2026 年)

データモデルではなく、ビジュアルのマトリックスを対象とする計算です。

関数目的
FIRST軸の最初の行の値
LAST軸の最後の行の値
PREVIOUS前の行の値
NEXT次の行の値
LOOKUPフィルターを適用した値(2025 年 6 月)
LOOKUPWITHTOTALS合計を考慮した、フィルター適用後の値(2025 年 6 月)

ビジュアル計算はビジュアルごとに定義され、セマンティックモデルには影響しません。

カレンダーベースのタイムインテリジェンス(2025 年 9 月プレビュー)

8 つの新しい週ベースの関数を使って、カスタムカレンダー(会計年度、小売、13 か月、太陰暦)を定義できます。

関数目的
TOTALWTD週次累計
CLOSINGBALANCEWEEK週の期末残高
OPENINGBALANCEWEEK週の期首残高
STARTOFWEEK現在の週の最初の日付
ENDOFWEEK現在の週の最後の日付
NEXTWEEK次の週の日付テーブル
PREVIOUSWEEK前の週の日付テーブル
DATESWTD週次累計の日付フィルター

有効化: File > Options > Preview features > Enhanced DAX Time Intelligence

動的な書式文字列

テキストに変換せずに、コンテキストに応じた書式を適用します(Desktop および Report Server で 2025 年 1 月以降 GA)。

// Dynamic format string for currency
Total Sales =
SUM(Sales[Amount])

// Format string expression (set in measure properties):
// = IF(SELECTEDVALUE(Currency[Code]) = "EUR", "€#,##0.00", "$#,##0.00")

FORMAT() に対する利点: 数値データ型を維持するため、グラフの描画や並べ替えが正しく行われます。

TABLEOF と NAMEOF(2026 年 2 月)

名前の変更に自動的に対応するモデルオブジェクトを参照します。

// NAMEOF returns the name of a column/measure/calendar as text
NAMEOF(Sales[Amount])  // Returns "Amount"

// TABLEOF returns a reference to the table of a column/measure
TABLEOF(Sales[Amount])  // Returns reference to Sales table

UDF 内で使うと、名前の変更に強い安全なコードを作成できます。

よくあるアンチパターン

アンチパターン問題修正方法
CALCULATE の引数に FILTER(table, ...) を使うテーブル全体をスキャンし、エンジンによる最適化が行われませんブール式のフィルターを使います:column = value
CALCULATE のネストコンテキストの上書きがわかりにくくなります複数のフィルターを指定した単一の CALCULATE を使います
単純な合計にテーブル全体への SUMX を使う不要なイテレーターです列を単純に集計する場合は SUM() を使います
並べ替え用のメジャーで FORMAT() を使うテキストが返されるため、数値として並べ替えられません個別の並べ替え列を使います
集計に計算列を使う行ごとに保存され、メモリを無駄に消費します代わりにメジャーを使います
COUNTROWS(FILTER(table,...))CALCULATE(COUNTROWS(table), filter) より遅くなりますフィルターを指定した CALCULATE を使います
メジャー間で DAX をコピー&ペーストする保守が難しく、エラーが発生しやすくなりますUDF(プレビュー)を使って再利用可能なロジックを定義します
条件付き表示に FORMAT() を使うテキストが返され、並べ替えやグラフに支障が出ます代わりに動的な書式文字列を使います
EARLIER() の使いすぎわかりにくく、レガシーなパターンですVAR を使って外側のコンテキストを保持します
ウィンドウ関数で MATCHBY を無視する行の識別が曖昧になりますパーティションに重複がある場合は、必ず MATCHBY を指定します

その他のリソース

リファレンスファイル
  • references/dax-function-categories.md -- INFO 関数、ウィンドウ関数、2025~2026 年の追加機能を含む、カテゴリ別の完全な関数リファレンス
  • references/dax-patterns-advanced.md -- 仮想リレーションシップ、動的セグメンテーション、親子階層、バスケット分析などの高度なパターン

コメント