dax-mastery について
Power BI のモデル作成者向け DAX リファレンスです。評価コンテキスト、計算、時間インテリジェンス、イテレーター、パフォーマンスのパターンを解説し、計算グループや新しい言語機能も扱います。
主な機能
- 01行コンテキストとフィルターコンテキスト
- 02CALCULATE のフィルター動作
- 03時間インテリジェンス関数とパターン
- 04イテレーター関数とテーブル関数
- 05計算グループとフィールドパラメーター
- 06ウィンドウ計算とビジュアル計算
活用シーン
- 01メジャーと計算列の作成
- 02前年比やローリング期間の分析
- 03DAX 式のパフォーマンス改善
- 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) | 対象列のフィルターを置き換えます |
| REMOVEFILTERS | REMOVEFILTERS(Products[Color]) | 列の既存のフィルターを削除します |
| ALL | ALL(Products) | テーブルのすべてのフィルターを削除します |
| KEEPFILTERS | KEEPFILTERS(Products[Color] = "Red") | 既存のフィルターと交差させます |
| USERELATIONSHIP | USERELATIONSHIP(Sales[ShipDate], Date[Date]) | 非アクティブなリレーションシップを有効にします |
| CROSSFILTER | CROSSFILTER(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-- 仮想リレーションシップ、動的セグメンテーション、親子階層、バスケット分析などの高度なパターン