7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DAXクエリで学ぶマトリックス構築 ― 第1回 DAXクエリとマトリックス思考

Last updated at Posted at 2025-12-03

第1回:DAXメジャーの基礎とDAXクエリによる学習環境

1.1 はじめに

DAXメジャーは、Power BIでデータを集計・分析するための最も重要な機能である。売上合計、前年比、構成比など、あらゆるビジネス指標はメジャーで表現される。

このシリーズでは、メジャーを学ぶ際にDAX Studioという補助ツールを併用する。

Power BIでメジャーを作ると、結果は「単一の数値」しか表示されない。このため、「内部で何が起きているか」「どのデータが集計されているか」が見えにくい。

DAX StudioではDAXクエリを使い、計算過程をテーブル形式で可視化できる。これにより

  • Filter Contextの動作が目で確認できる
  • 複雑な計算を段階的に理解できる
  • エラーの原因を特定しやすい

1.2 DAXメジャーとは何か

1.2.1 メジャーの定義

メジャー(Measure) とは、Power BIで動的に計算される集計値である。

  • ビジュアルやフィルタの状態に応じて計算される
  • データテーブルには保存されない
  • 常に**単一の値(スカラー値)**を返す
Total Sales = SUM(Sales[Amount])

このメジャーは、ビジュアルの状態によって異なる値を返す。

  • フィルタなし → 全売上
  • Category = "Electronics" でフィルタ → Electronicsの売上のみ
  • Year = 2023 でフィルタ → 2023年の売上のみ

1.2.2 メジャーが動的である理由

メジャーはFilter Contextの中で評価される。

Filter Contextとは「今、どのデータが見えているか」という状態のこと。ビジュアル、スライサー、フィルタペインなどがFilter Contextを作り出す。

同じメジャーでも、Filter Contextが変われば結果も変わる。これがメジャーの本質である。

1.3 メジャーと計算列の違い

DAXで計算を行う方法は2つある。メジャー計算列。両者の違いを理解することが重要である。

1.3.1 比較表

項目 メジャー 計算列
計算タイミング クエリ実行時(動的) データ更新時(静的)
保存場所 データモデルに保存されない テーブルに物理的に保存される
コンテキスト Filter Context Row Context
用途 集計、分析指標 行ごとの分類、計算
パフォーマンス 軽量(ストレージ不要) 重い(ストレージ使用)
返す値 スカラー値(単一の数値) 各行に値
DAXクエリでの定義 可能(DEFINE MEASURE) 不可能

1.3.2 メジャーの例

メジャー:動的に集計
Total Sales = SUM(Sales[Amount])

用途:売上合計、平均単価、顧客数など、集計が必要な場合

1.3.3 計算列の例

計算列:各行で計算(Power BIで作成)
Product[Profit] = Product[UnitPrice] - Product[UnitCost]

用途:各製品の利益、カテゴリ分類、フラグ設定など、行ごとの計算が必要な場合

1.3.4 DAXクエリと計算列の重要な違い

計算列はDAXクエリ内で定義できない

理由

  • 計算列はテーブルに物理的に保存される
  • DAXクエリは一時的な結果を返すだけで、データモデルを変更できない
  • 計算列を追加するには、Power BI Desktopで直接テーブルに追加する必要がある

DAXクエリでできること

  • メジャーの定義(DEFINE MEASURE)
  • 一時的な計算列の表示(ADDCOLUMNSで疑似的に)

DAXクエリでできないこと

  • 永続的な計算列の作成
  • データモデルの変更

1.3.5 使い分けの原則

原則:集計にはメジャーを使う

  • メジャーを使うべき場合:SUM、AVERAGE、COUNT、比率計算など
  • 計算列を使うべき場合:行単位の分類、グループ化用の新しい列
  • 計算列を避けるべき場合:集計値(メジャーの方がパフォーマンスが良い)

1.4 環境のセットアップ

1.4.1 準備:必要なツールとデータ

1. Power BI Desktop(無料)

2. DAX Studio(無料)

3. サンプルデータ:AdventureWorks Sales

1.4.2 DAX Studioの起動と接続

手順

  1. Power BI Desktop でサンプルファイルを開く
  2. Power BIの「外部ツール」メニューから「DAX Studio」を起動する。

これで、Power BIのデータモデルに対してDAXクエリを実行できる。

1.5 DAXクエリとは何か

1.5.1 DAXクエリの基本

DAXクエリは、Power BIのメジャーとは異なり、テーブル全体を返す。

比較

項目 DAXメジャー DAXクエリ
返す値 スカラー値(数値1つ) テーブル(複数行×複数列)
実行環境 Power BI Desktop DAX Studio
用途 ビジュアルでの表示 学習、デバッグ、検証
メジャー定義 UIで作成 DEFINE MEASUREで定義

DAXクエリは学習ツールであり、最終的にはPower BIでメジャーを作成する。

1.5.2 EVALUATEの基本構文

DAXクエリは必ず EVALUATE で始まる。

EVALUATE
<テーブル式>
例1:テーブルをそのまま表示
EVALUATE Product
例2:フィルタしたテーブル
EVALUATE
FILTER(Product, Product[Color] = "Red")

1.6 DAXクエリでメジャーを定義する方法

1.6.1 DEFINE MEASURE の基本構文

DAXクエリ内でメジャーを定義するには、DEFINE MEASURE を使用する。

DEFINE
    MEASURE テーブル名[メジャー名] = <DAX式>
EVALUATE
<テーブル式>

重要なルール

  • メジャーは必ず テーブル名[メジャー名] の形式で定義
  • DEFINE セクションは EVALUATE の前に記述
  • 複数のメジャーを定義可能

1.6.2 最初のメジャー定義例

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Sales", [Total Sales]
)
ORDER BY Product[Category]

結果

image.png

何が起きているか

  1. MEASURE Sales[Total Sales] でメジャーを定義
  2. SUMMARIZECOLUMNSがProduct[Category]でグループ化
  3. 各カテゴリに対して [Total Sales] メジャーが評価される
  4. 結果がテーブルとして返される

SUMとSUMXの使い分け

SUMは単一列の値をそのまま合計する。事前に計算済みの列がある場合に使用する。

Total Amount = SUM(Sales[Amount])

SUMXは各行で式を評価してから合計する。複数列の計算が必要な場合に使用する。

Total Sales = SUMX(Sales, Sales[Quantity] * Sales[Net Price])

使い分けの基準

  • 合計対象の列が既に存在する → SUM
  • 行ごとに計算が必要(数量×単価など)→ SUMX

SUMの方がシンプルで高速だが、計算列を事前に作る必要がある。SUMXは計算列なしで柔軟な集計が可能である。

1.6.3 複数のメジャーを定義

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Total Quantity] =
        SUM ( Sales[Quantity] )
    MEASURE Sales[Average Price] =
        DIVIDE (
            [Total Sales],
            [Total Quantity]
        )
    MEASURE Sales[Customer Count] =
        DISTINCTCOUNT ( Sales[CustomerKey] )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Sales", [Total Sales],
    "Quantity", [Total Quantity],
    "Avg Price", [Average Price],
    "Customers", [Customer Count]
)
ORDER BY Product[Category]

image.png

ポイント

  • 複数のメジャーを1つのDEFINEセクションで定義
  • メジャー内で他のメジャーを参照可能([Total Sales][Total Quantity]
  • メジャー名を [] で囲んで参照

1.6.4 変数(VAR)との組み合わせ

DEFINEセクションには、MEASUREとVARの両方を定義できる。

売上上位3カテゴリを抽出
DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Total Quantity] = SUM(Sales[Quantity])
    
    VAR TopCategories = 
        TOPN(
            3,
            VALUES(Product[Category]),
            [Total Sales],
            DESC
        )
    
    VAR ResultTable = 
        ADDCOLUMNS(
            TopCategories,
            "Sales", [Total Sales],
            "Quantity", [Total Quantity]
        )

EVALUATE
    ResultTable
ORDER BY [Sales] DESC

image.png

構文ルール

  • MEASURE:テーブル名[メジャー名] の形式
  • VAR:単純に変数名のみ
  • 両方を同じDEFINEセクションで定義可能

1.7 コンテキストの基礎理解:最重要概念

1.7.1 DAXの2つのコンテキスト

コンテキスト 意味 発生場所 使用例
Row Context 「今、この行を見ている」 計算列、イテレータ関数 行ごとの利益計算
Filter Context 「今、このデータが見えている」 メジャー、ビジュアル 売上合計、顧客数

1.7.2 Row Context の理解

計算列での例(Power BIで作成)

Product テーブルに以下の計算列を作成

Profit = Product[Unit Price] - Product[Unit Cost]

この式は各行ごとに評価される。

image.png

Row Contextの特徴

  • 「現在の行」という概念が存在する
  • 列を参照すると、その行の値を取得する
  • テーブル全体を集計する関数(SUM、AVERAGEなど)は使えない

DAXクエリでのRow Context

計算列はDAXクエリで永続的に作成できないが、ADDCOLUMNSで一時的に表示できる。

EVALUATE
ADDCOLUMNS(
    TOPN(5, Product),
    "Profit", Product[UnitPrice] - Product[UnitCost]
)

image.png

1.7.3 Filter Context の理解

メジャーでの例

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Sales", [Total Sales]
)

このメジャーは、現在のFilter Contextで評価される。

結果

image.png

何が起きているか

  • 1行目:Filter Context = "Category = Audio" → Audioの売上のみ集計
  • 2行目:Filter Context = "Category = TV and Video" → TV and Videoの売上のみ集計
  • 3行目:Filter Context = "Category = Computers" → Computersの売上のみ集計

Filter Contextの特徴

  • ビジュアル、スライサー、フィルタがFilter Contextを作る
  • メジャーは常にFilter Context内で評価される
  • 「どのデータが見えているか」を決定する

1.7.4 DAXクエリでコンテキストを確認

Filter Contextの可視化

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    Product[Subcategory],
    "Sales", [Total Sales]
)
ORDER BY
    Product[Category],
    Product[Subcategory]

image.png

観察すべきポイント

  • 各行(Category + Subcategory の組み合わせ)で異なる値
  • これは、各行に異なるFilter Contextが適用されているため

Row Contextの可視化

EVALUATE
ADDCOLUMNS(
    TOPN(5, Product),
    "Profit", Product[Unit Price] - Product[Unit Cost],
    "Profit Margin", 
        DIVIDE(
            Product[Unit Price] - Product[Unit Cost],
            Product[Unit Price]
        )
)

image.png

観察すべきポイント

  • ADDCOLUMNSは各行を順番に処理(Row Context)
  • 各行で Product[Unit Price] は「その行の値」を参照

1.8 SUMMARIZECOLUMNS:マトリックスの作成

1.8.1 SUMMARIZECOLUMNSとは

SUMMARIZECOLUMNSは、Power BIのマトリックスビジュアルと同じ構造のテーブルを作る関数である。

基本構文
SUMMARIZECOLUMNS(
    <グループ化する列1>,
    <グループ化する列2>,
    ...
    "メジャー表示名1", <メジャー参照1>,
    "メジャー表示名2", <メジャー参照2>,
    ...
)

1.8.2 基本例

カテゴリ別売上
DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Sales", [Total Sales]
)
ORDER BY Product[Category]

結果

image.png

これは、Power BIで以下を設定したマトリックスと同じ

  • 行:Product[Category]
  • 値:Total Sales メジャー

1.8.3 複数のメジャーを表示

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Total Quantity] =
        SUM ( Sales[Quantity] )
    MEASURE Sales[Customer Count] =
        DISTINCTCOUNT ( Sales[CustomerKey] )
    MEASURE Sales[Average Price] =
        DIVIDE (
            [Total Sales],
            [Total Quantity]
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Sales", [Total Sales],
    "Quantity", [Total Quantity],
    "Customers", [Customer Count],
    "Avg Price", [Average Price]
)
ORDER BY Product[Category]

結果

image.png

1.8.4 階層化

複数列でグループ化
DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
EVALUATE
SUMMARIZECOLUMNS(
    Product[Category],
    Product[Subcategory],
    "Sales", [Total Sales]
)
ORDER BY 
    Product[Category],
    Product[Subcategory]

結果

image.png

これは、Power BIで以下を設定したマトリックスと同じ

  • 行:Product[Category] → Product[Subcategory](階層)
  • 値:Total Sales

1.9 Power BIでメジャーを作成する

1.9.1 メジャーの作成手順

DAXクエリで動作を確認したメジャーを、Power BIで実装する。

手順1:テーブルを選択

  1. Power BI Desktopで サンプルファイル を開く
  2. 右側の「データ」ペインで、メジャーを配置したいテーブルを選択
    • 推奨:Sales テーブル(売上関連のメジャーを集約)

手順2:新しいメジャーを作成

  1. ホームタブ → 「新しいメジャー」をクリック
  2. 数式バーに以下を入力
Sales Amount = SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )
  1. Enter キーで確定

手順3:メジャーの確認

  1. 「データ」ペインの Sales テーブル配下に「Total Sales」が追加される
  2. アイコンが電卓マークであることを確認

image.png

1.9.2 基本的なメジャーの作成例

以下のメジャーを順番に作成してみよう。

メジャー1:売上合計

Total Sales = SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )

メジャー2:数量合計

Total Quantity = SUM(Sales[Quantity])

メジャー3:平均単価

Average Unit Price = DIVIDE([Total Sales], [Total Quantity])

DIVIDE関数を使う理由

  • ゼロ除算を自動的に処理
  • エラーを回避できる
  • 代替値を指定可能(第3引数)

メジャー4:顧客数

Customer Count = DISTINCTCOUNT(Sales[CustomerKey])

DISTINCTCOUNT vs COUNT

  • DISTINCTCOUNT:重複を除いたユニークな数
  • COUNT:すべての行数(重複含む)

1.9.3 メジャーをビジュアルで確認

手順1:マトリックスビジュアルの作成

  1. 「視覚化」ペインから「マトリックス」を選択
  2. 以下のようにフィールドを配置
    • :Product[Category]
    • :Total Sales, Total Quantity, Average Unit Price, Customer Count

結果イメージ

image.png

これで、メジャーが正しく動作していることが確認できる。

1.9.4 スライサーでFilter Contextを確認

手順

  1. 「スライサー」ビジュアルを追加
  2. Calendar[Year] をスライサーに配置
  3. 年度を変更すると、マトリックスの値が変わることを確認

観察すべきポイント

  • 同じメジャー「Total Sales」が、年度選択によって異なる値を返す
  • これがFilter Contextの動作である
  • メジャーは常に「現在のFilter Context」で評価される

1.10 実務で使う基本メジャーのパターン

1.10.1 集計メジャー

/* コードを簡略にするため、金額合計のSales[Amount]の列があるとする。 */
-- 合計
Total Sales = SUM(Sales[Amount])

-- 平均
Average Sales = AVERAGE(Sales[Amount])

-- 最大・最小
Max Sales = MAX(Sales[Amount])
Min Sales = MIN(Sales[Amount])

-- 件数
Transaction Count = COUNTROWS(Sales)

-- ユニーク件数
Customer Count = DISTINCTCOUNT(Sales[CustomerKey])
Product Count = DISTINCTCOUNT(Sales[ProductKey])

1.10.2 計算メジャー

-- 除算(ゼロ除算対策)
Average Unit Price = 
DIVIDE(
    [Total Sales],
    [Total Quantity]
)

-- 構成比
Sales Share = 
DIVIDE(
    [Total Sales],
    CALCULATE([Total Sales], ALL(Product[Category]))
)

-- 利益率
Profit Margin = 
DIVIDE(
    [Total Sales] - [Total Cost],
    [Total Sales]
)

1.10.3 条件付きメジャー

-- 条件付き集計
High Value Sales = 
CALCULATE(
    [Total Sales],
    Sales[Unit Price] >= 1000
)

-- 複数条件
Premium Computers Sales = 
CALCULATE(
    [Total Sales],
    Product[Category] = "Computers",
    Sales[Unit Price] >= 1000
)

1.11 DAXクエリでメジャーの動作を検証

1.11.1 Power BIとDAXクエリの対応

Power BIで作成するメジャー

Total Sales = 
    SUMX (
        Sales,
        Sales[Quantity] * Sales[Net Price]
    )
Total Cost = SUM(Sales[Total Cost])
Gross Profit = [Total Sales] - [Total Cost]
Profit Margin = DIVIDE([Gross Profit], [Total Sales])

DAXクエリで同じメジャーを定義して検証

DEFINE
    MEASURE Sales[Total Sales] = 
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Total Cost] = SUM(Sales[Unit Cost])
    MEASURE Sales[Gross Profit] = [Total Sales] - [Total Cost]
    MEASURE Sales[Profit Margin] = 
        DIVIDE([Gross Profit], [Total Sales])
EVALUATE
SUMMARIZECOLUMNS(
    Product[Category],
    Product[Subcategory],
    "Sales", [Total Sales],
    "Cost", [Total Cost],
    "Profit", [Gross Profit],
    "Margin", [Profit Margin]
)
ORDER BY [Profit Margin] DESC

image.png

メリット

  • メジャー間の依存関係が明確
  • 計算結果をテーブルで一覧確認
  • どのサブカテゴリが高利益率かが一目瞭然

1.11.2 変数を活用した高度な例

DEFINE
    -- 売上金額(数量 × 単価)
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )

    -- 原価(数量 × 仕入単価)
    MEASURE Sales[Total Cost] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Unit Cost]
        )

    -- カテゴリごとの顧客数を合計
    MEASURE Sales[Customer Count] =
        SUMX (
            VALUES ( Product[Category] ),    -- 現在のカテゴリで1行ずつ処理
            CALCULATE (
                DISTINCTCOUNT ( Sales[CustomerKey] )   -- そのカテゴリのユニーク顧客数
            )
        )

    -- 1顧客あたり平均売上
    VAR SalesPerCustomer =
        DIVIDE (
            [Total Sales],
            [Customer Count]
        )

    -- 1顧客あたり売上
    MEASURE Sales[Sales per Customer] =
        DIVIDE (
            [Total Sales],
            [Customer Count]
        )

    -- 高額顧客フラグ(平均より高いかを判定)
    MEASURE Sales[High Value Customer Flag] =
        IF (
            [Sales per Customer] > SalesPerCustomer,   -- 変数で計算した平均と比較
            "High Value",
            "Standard"
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Sales", [Total Sales],
    "Customers", [Customer Count],
    "Sales per Customer", [Sales per Customer],
    "Customer Tier", [High Value Customer Flag]
)
ORDER BY [Sales per Customer] DESC    -- 顧客あたり売上の高い順に並べる

image.png

注意 VARはDEFINEセクションとMEASURE内の両方で使用できるが、用途が異なる。

1.12 よくある間違いと解決方法

間違い1:計算列とメジャーを混同する

メジャーで行参照しようとする
DEFINE
    MEASURE Product[Wrong Profit] = 
        Product[Unit Price] - Product[Unit Cost]  -- エラー!

メジャーにはRow Contextがない

解決方法:

Power BIで計算列を作成
Product[Profit] = Product[Unit Price] - Product[Unit Cost]
または、DAXクエリでADDCOLUMNSを使う(一時的)
EVALUATE
ADDCOLUMNS(
    Product,
    "Profit", Product[Unit Price] - Product[Unit Cost]
)

間違い2:集計を計算列で行おうとする

計算列で集計
Total Sales =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )  -- 全て合計値となる

計算列にはFilter Contextがないため、全て合計値となる(Row Contextのみ)

解決方法:

メジャーを使う
DEFINE
    MEASURE Sales[Total Sales] = SUM(Sales[Amount])
CALCULATEでFilter Contextを発生させる
Total Sales =
    CALCULATE (
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    )

間違い3:ゼロ除算のエラー処理をしない

ゼロ除算の可能性
DEFINE
    MEASURE Sales[Average Price] = 
        SUM(Sales[Amount]) / SUM(Sales[Quantity])  -- 危険!

数量がゼロの場合、エラーになる

解決方法:

DIVIDEを使う
DEFINE
    MEASURE Sales[Average Price] = 
        DIVIDE(SUM(Sales[Amount]), SUM(Sales[Quantity]))
代替値を指定
DEFINE
    MEASURE Sales[Average Price] = 
        DIVIDE(SUM(Sales[Amount]), SUM(Sales[Quantity]), 0)

間違い4:DAXクエリで計算列を永続的に作ろうとする

問題点: DAXクエリはデータモデルを変更できない

解決方法:

Power BIで直接計算列を作成

または、DAXクエリでADDCOLUMNSを使って一時的に表示

EVALUATE
ADDCOLUMNS(
    Product,
    "Profit", Product[UnitPrice] - Product[UnitCost]
)

参考文献と学習リソース

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?