5
0

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クエリで学ぶマトリックス構築 ― 第2回 CALCULATE

Last updated at Posted at 2025-12-04

第2回:CALCULATE

今回使用するサンプルデータは、以下のサイトからダウンロードしてください。

1.CALCULATEの基本構文

1.1. CALCULATEとは何か

CALCULATEは、Filter Contextを変更して式を評価する関数である。

基本構文:

CALCULATE(
    <式>,
    <フィルタ条件1>,
    <フィルタ条件2>,
    ...
)

1.2. 最もシンプルな例

DEFINE
    MEASURE Sales[Sales Amount] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Red Sales] =
        CALCULATE (
            [Sales Amount],
            Product[Color] = "Red"
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Brand],
    "Total Sales", [Sales Amount],
    "Red Sales", [Red Sales]
)

結果:

image.png

数値の表示を整えます。

DEFINE
    MEASURE Sales[Sales Amount] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Red Sales] =
        CALCULATE (
            [Sales Amount],
            Product[Color] = "Red"
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Brand],
    "Total Sales",
        FORMAT (
            [Sales Amount],
            "$#,##0"
        ),
    "Red Sales",
        FORMAT (
            [Red Sales],
            "$#,##0"
        )
)
ORDER BY Sales[Sales Amount] DESC

image.png

1.3. CALCULATEの動作原理

CALCULATEは以下のステップで動作する:

  1. 既存のFilter Contextを取得
  2. 指定されたフィルタ条件を適用(追加、削除、変更)
  3. 新しいFilter Contextで式を評価
  4. 結果を返す

重要:CALCULATEは元のFilter Contextを変更せず、新しいFilter Contextを作成する。

1.4. CALCULATEによるFilter Contextの変更パターン

1.4.1. パターン1:フィルタの追加

既存のFilter Contextに、さらにフィルタを追加する。

DEFINE
    MEASURE Sales[Sales Amount] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Red Sales] =
        CALCULATE (
            [Sales Amount],
            Product[Color] = "Red"
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Brand],
    "Total Sales",
        FORMAT (
            [Sales Amount],
            "$#,##0"
        ),
    "Red Sales",
        FORMAT (
            [Red Sales],
            "$#,##0"
        )
)
ORDER BY Sales[Sales Amount] DESC

image.png

動作:

  • 既存のFilter Context(各カテゴリ)
  • + Color = "Red" のフィルタ
  • = 赤色の商品の売上のみ

1.4.2. パターン2:フィルタの上書き

同じ列に対するフィルタは、上書きされる。

DEFINE
    MEASURE Sales[Sales Amount] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Contoso Sales] =
        CALCULATE (
            [Sales Amount],
            Product[Brand] = "Contoso"
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Brand],
    "Total Sales",
        FORMAT (
            [Sales Amount],
            "$#,##0"
        ),
    "Contoso Sales",
        FORMAT (
            [Contoso Sales],
            "$#,##0"
        )
)
ORDER BY [Sales Amount] DESC

image.png

動作:

  • 既存のFilter Context(例:Brand)
  • CALCULATEで Brand = "Contoso" を指定
  • → Brand の全てフィルターが Brand = "Contoso"上書きされる

外部フィルターを保持し、内部フィルターを追加するにはKEEPFILTERSを使います。

DEFINE
    MEASURE Sales[Sales Amount] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Contoso Sales] =
        CALCULATE (
            [Sales Amount],
            KEEPFILTERS ( Product[Brand] = "Contoso" )
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Brand],
    "Total Sales",
        FORMAT (
            [Sales Amount],
            "$#,##0"
        ),
    "Contoso Sales",
        FORMAT (
            [Contoso Sales],
            "$#,##0"
        )
)
ORDER BY Sales[Sales Amount] DESC

image.png

1.4.3. パターン3:複数列のフィルタ

DEFINE
    MEASURE Sales[Sales Amount] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Red Computers Sales] =
        CALCULATE (
            [Sales Amount],
            Product[Color] = "Red",
            Product[Category] = "Computers"
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Brand],
    "Total Sales",
        FORMAT (
            [Sales Amount],
            "$#,##0"
        ),
    "Red Computers Sales",
        FORMAT (
            [Red Computers Sales],
            "$#,##0"
        )
)
ORDER BY Sales[Sales Amount] DESC

image.png

動作:

  • ColorとCategoryの両方にフィルタを適用
  • 複数条件はAND条件として扱われる

1.5. ALL関数ファミリー:フィルタの削除

1.5.1. ALL:すべてのフィルタを削除

ALLは、指定したテーブルまたは列のフィルタをすべて削除する。

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[All Products Sales] =
        CALCULATE (
            [Total Sales],
            ALL ( Product )
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Total Sales",
        FORMAT (
            [Total Sales],
            "$#,##0"
        ),
    "All Products Sales",
        FORMAT (
            [All Products Sales],
            "$#,##0"
        )
)
ORDER BY Sales[Sales Amount] DESC

結果:

image.png

何が起きているか:

  • "Total Sales"は各カテゴリでフィルタされる
  • "All Products Sales"は、ALL(Product) で Product テーブルのすべてのフィルタが削除される
  • 結果として、全製品の売上が返る

以下の様に比率を計算する際の分母でよく使われる。

1.5.2. 実務での使用例:構成比

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Sales Share] =
    	DIVIDE(
    		[Total Sales],
	        CALCULATE (
    	        [Total Sales],
    	        ALL ( Product )
    	    )
   		)

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Total Sales",
        FORMAT (
            [Total Sales],
            "$#,##0"
        ),
    "Sales Share",
        FORMAT (
            [Sales Share],
            "##0.0%"
        )
)
ORDER BY Sales[Sales Amount] DESC

計算式:

  • 分子:各カテゴリの売上(Filter Contextあり)
  • 分母:全カテゴリの売上(Filter Contextを削除)
  • = 構成比

上位3の売り上げと売上比率

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Sales Share] =
    	DIVIDE(
    		[Total Sales],
	        CALCULATE (
    	        [Total Sales],
    	        ALL ( Product )
    	    )
   		)
   	
   	VAR TopCategories =
   		TOPN(
   			3,
   			VALUES(Product[Category]),
   			[Total Sales],
   			DESC
   		)

EVALUATE
ADDCOLUMNS( 
    TopCategories,
    "Total Sales",
        FORMAT (
            [Total Sales],
            "$#,##0"
        ),
    "Sales Share",
        FORMAT (
            [Sales Share],
            "##0.0%"
        )
)
ORDER BY Sales[Sales Amount] DESC

結果:

image.png

1.5.3 ALL vs ALLSELECTED

関数 動作 使用場面
ALL すべてのフィルタを削除 絶対値ベースの計算(全体に対する構成比)
ALLSELECTED ビジュアルレベルのフィルタは保持 相対値ベースの計算(表示されているデータ内での構成比)
DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Share of All] =
        DIVIDE (
            [Total Sales],
            CALCULATE (
                [Total Sales],
                ALL ( Product )
            )
        )
    MEASURE Sales[Share of Selected] =
        DIVIDE (
            [Total Sales],
            CALCULATE (
                [Total Sales],
                ALLSELECTED ( Product )
            )
        ) -- SUMMARIZECOLUMNSにスライサーを直接指定

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    TREATAS (          -- Color のスライサーで Red を選択
        {
            "Red"
        },
        'Product'[Color]
    ),
    "Sales",
        FORMAT (
            [Total Sales],
            "$#,###"
        ),
    "Share of All",
        FORMAT (
            [Share of All],
            "##0.00%"
        ),
    "Share of Selected",
        FORMAT (
            [Share of Selected],
            "##0.00%"
        )
)
ORDER BY Product[Category]

image.png

違い:

  • ALL:データモデル全体に対する構成比
  • ALLSELECTED:ビジュアルで選択されているデータに対する構成比

1.5.4. ALLEXCEPT:特定列以外のフィルタを削除

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Sales by Category Only] =
        CALCULATE (
            [Total Sales],
            ALLEXCEPT (
                Product,
                Product[Category]
            )
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    Product[Subcategory],
    "Sales",
        FORMAT (
            [Total Sales],
            "$#,##0"
        ),
    "Sales by Category Only",
        FORMAT (
            [Sales by Category Only],
            "$#,##0"
        )
)
ORDER BY
    Product[Category],
    Product[Subcategory]

image.png

動作:

  • Product[Category] のフィルタは保持
  • それ以外(Subcategory、Brand等)のフィルタは削除
  • カテゴリごとの合計売上が各サブカテゴリ行に表示される

1.6. REMOVEFILTERS vs ALL

1.6.1. 2つの関数の違い

関数 動作 推奨
REMOVEFILTERS フィルタのみを削除 推奨
ALL フィルタを削除し、テーブル全体を返す 副作用に注意

1.6.2. REMOVEFILTERSの使用(推奨)

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[All Products Sales] =
        CALCULATE (
            [Total Sales],
            REMOVEFILTERS ( Product[Category] )
        )

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

image.png

推奨理由:

  • 意図が明確(特定のフィルタの削除のみ)
  • パフォーマンスが良い
  • 予期しない副作用がない

1.6.3. 複数列のフィルタ削除

DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[No Product Filters] =
        CALCULATE (
            [Total Sales],
            REMOVEFILTERS (
                Product[Category],
                Product[Subcategory]
            )
        )
    -- または
    MEASURE Sales[No Product Filters 2] =
        CALCULATE (
            [Total Sales],
            REMOVEFILTERS ( Product ) -- Productテーブル全体
        )

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

image.png

1.7. FILTER関数:複雑な条件のフィルタリング

1.7.1. FILTER関数の基本

FILTERは、テーブルの各行を評価してフィルタする関数である。

基本構文:

FILTER(
    <テーブル>,
    <条件式>
)

1.7.2. 単純な条件式との違い

-- 方法1:単純な条件式(推奨:シンプルな場合)
DEFINE
    MEASURE Sales[Computers Sales] = 
        CALCULATE(
            [Total Sales],
            Product[Category] = "Computers"
        )

-- 方法2:FILTER関数(推奨:複雑な条件の場合)
DEFINE
    MEASURE Sales[Computers Sales 2] = 
        CALCULATE(
            [Total Sales],
            FILTER(Product, Product[Category] = "Computers")
        )

両者は同じ結果だが、使い分けがある。

1.7.3. FILTERが必要な場合

OR条件

2021年3月以前は、複数列にまたがるOR条件を書く場合、明示的なFILTERが必要だったが、2021年3月から、新しい構文が導入され、複数列のOR条件も簡潔に書けるようになった。

2021年3月以前
DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Red or Contoso Sales] =
        CALCULATE (
            [Total Sales],
            FILTER (             -- OR条件はFILTERを使わなければならなかった
                ALL (
                    Product[Color],
                    Product[Brand]
                ),
                Product[Color] = "Red"
                    || Product[Brand] = "Contoso"
            )
        )

EVALUATE
SUMMARIZECOLUMNS (
    Product[Category],
    "Total Sales", [Total Sales],
    "Red or Contoso Sales", [Red or Contoso Sales]
)
2021年3月以降
DEFINE
    MEASURE Sales[Total Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Net Price]
        )
    MEASURE Sales[Red or Contoso Sales] =
        CALCULATE (
            [Total Sales],
            Product[Color] = "Red"
                || Product[Brand] = "Contoso"  -- CALCULATEでOR条件が書ける
        )

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

1.7.4. FILTERのパフォーマンス注意点

FILTERは行ごとに評価されるため、パフォーマンスに影響する

-- 遅い:FILTERを使いすぎ
DEFINE
    MEASURE Sales[Slow Measure] = 
        CALCULATE(
            [Total Sales],
            FILTER(Sales, Sales[Amount] > 100),
            FILTER(Sales, Sales[Quantity] > 1),
            FILTER(Product, Product[Category] = "Electronics")
        )

-- 速い:単純な条件式を使う
DEFINE
    MEASURE Sales[Fast Measure] = 
        CALCULATE(
            [Total Sales],
            Sales[Amount] > 100,
            Sales[Quantity] > 1,
            Product[Category] = "Electronics"
        )

原則:

  • 単純な条件(1列、1値)→ 単純な条件式
  • 複雑な条件(計算、複数列)→ FILTER関数
5
0
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
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?