---
title: The Definitive Guide to DAX #4
tags:  #powerbi #dax  
author: [fukuyori](https://www.docswell.com/user/Fukuyori)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/V7P9LNZ2J8.jpg?width=480
description: The Definitive Guide to DAX Chapter 4 勉強用スライド
published: March 26, 23
canonical: https://www.docswell.com/s/Fukuyori/KJLLE3-2023-03-26-194635
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/V7P9LNZ2J8.jpg)

The Definitive Guide
to DAX
Chapter 4
Understanding evaluation contexts （評価の背景を理解する）


# Page. 2

![Page Image](https://bcdn.docswell.com/page/2JVMQKWXJQ.jpg)

この章で学ぶこと


# Page. 3

![Page Image](https://bcdn.docswell.com/page/5EGGWQDREL.jpg)

この章で学ぶこと


# Page. 4

![Page Image](https://bcdn.docswell.com/page/4JQX3K1YEP.jpg)

この章で学ぶこと


# Page. 5

![Page Image](https://bcdn.docswell.com/page/K7461PRZE1.jpg)

この章で学ぶこと


# Page. 6

![Page Image](https://bcdn.docswell.com/page/LJ1VG9QDEG.jpg)

この章で学ぶこと


# Page. 7

![Page Image](https://bcdn.docswell.com/page/GJWLKQM8E2.jpg)

計算列で以下の式の結果はどうなりますか。
Sales[SumOfSalesQuantity] = SUM(Sales[Quantity])
1.その行のQuantityの値、つまり各行で異なる値。
2.すべての行のQuantityの合計、つまり、全ての行で同じ値。
3.計算列の内部でSUMを使用することはできません。


# Page. 8

![Page Image](https://bcdn.docswell.com/page/4EZMZWQ9J3.jpg)

計算列で以下の式の結果はどうなりますか。
Sales[SumOfSalesQuantity] = SUM(Sales[Quantity])
1.その行のQuantityの値、つまり各行で異なる値。
2.すべての行のQuantityの合計、つまり、全ての行で同じ値。
3.計算列の内部でSUMを使用することはできません。


# Page. 9

![Page Image](https://bcdn.docswell.com/page/Y76NZG6D7V.jpg)

計算列で以下の式の結果はどうなりますか。
Sales[SumOfSalesQuantity] = SUM(Sales[Quantity])


# Page. 10

![Page Image](https://bcdn.docswell.com/page/G755WV6874.jpg)

計算列で以下の式の結果はどうなりますか。
Sales[SumOfSalesQuantity] = SUM(Sales[Quantity])
➢ この数式は、「現在のフィルタコン
テキストで表示されているすべて
の量の合計」を意味します。
➢ この場合、フィルタコンテキストが
存在しないため、テーブル全体を
計算します。


# Page. 11

![Page Image](https://bcdn.docswell.com/page/9J2NQ3MVER.jpg)

以下のメジャーの結果はどうなりますか。
GrossMargin% =
( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost]
1.この式は正しく動作します。
2.エラーです。この式は書くべきではありません。
3.数式を定義することはできますが、レポートで使用するとエラーが
返されます。 。


# Page. 12

![Page Image](https://bcdn.docswell.com/page/DEYPW1XQEM.jpg)

以下のメジャーの結果はどうなりますか。
GrossMargin% =
( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost]
1.この式は正しく動作します。
2.エラーです。この式は書くべきではありません。
3.数式を定義することはできますが、レポートで使用するとエラーが
返されます。 。


# Page. 13

![Page Image](https://bcdn.docswell.com/page/VJN5921278.jpg)

以下のメジャーの結果はどうなりますか。
GrossMargin% =
( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost]


# Page. 14

![Page Image](https://bcdn.docswell.com/page/YE9Y215DJ3.jpg)

以下のメジャーの結果はどうなりますか。
GrossMargin% =
( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost]
➢ メジャーは自動的に行コンテキスト
が発生しない。
➢ アグリゲータなしで値を取得しよう
としているが、どの行に対して計算
を行うか検出する方法がない。


# Page. 15

![Page Image](https://bcdn.docswell.com/page/GE8654Y57D.jpg)

イテレータで行コンテキストを使用する
SUMX(
Sales,
Sales[Net Price] * 1.1
)
➢ 最初のパラメータ Sales は、呼び出し元からのコンテキストを使用して評価され
る。
➢ 2番目のパラメータは、外部コンテキストと新しく作成された行コンテキストの両
方を使用して評価される。


# Page. 16

![Page Image](https://bcdn.docswell.com/page/LEL9Y643JR.jpg)

イテレータで行コンテキストを使用する
既存のコンテキストで最初のパラメータを評価し、スキャンする行を決定する。
前のステップで評価した各行に対して、新しい行コンテキストを作成する。
テーブルをイテレートし、既存のコンテキストと新しく作成された行コンテキストで2番目のパラメータを評価する。
前のステップで計算された値を集計する。


# Page. 17

![Page Image](https://bcdn.docswell.com/page/4JMZN5KMEW.jpg)

行コンテキストが存在するケース
➢計算列のDAX式が評価されるとき
➢イテレータ関数を使用した時


# Page. 18

![Page Image](https://bcdn.docswell.com/page/PJR6D3XL79.jpg)

イテレータ関数とは
➢ SUMX、AVERAGEX、MAXXなど、最後にXがつく関数
➢ ADDCOLUMNS
➢ FILTER


# Page. 19

![Page Image](https://bcdn.docswell.com/page/PEXM14M67X.jpg)

異なるテーブルのネストされた行コンテキスト
SUMX(
&#039;Products Category&#039;,
SUMX(
RELATEDTABLE( &#039;Product&#039; )
SUMX(
RELATEDTABLE( &#039;Sales&#039; )
Sales[Quantity]
* &#039;Product&#039;[Unit Price]
* &#039;Product Category&#039;[Discount]
)
)
)
3つのネストしたイテレータが含まれており、3つのテーブルをスキャンしている。


# Page. 20

![Page Image](https://bcdn.docswell.com/page/3EKG2ZGGJD.jpg)

同じテーブルのネストされた行コンテキスト
&#039;Product&#039;[UnitPriceRank] =
Productの現在の行の値
VAR
PriceOfCurrentProduct = &#039;Product&#039;[Unit Price]
VAR
MoreExpensiveProducts =
FILTERでイテレートされたProductの値
FILTER(
&#039;Product&#039;,
&#039;Product&#039;[Unit Price] &gt; PriceOfCurrentProduct
)
RETURN
COUNTROWS( MoreExpensiveProducts ) + 1
RANKXを使用しないで製品の価格が高いものからランク付けした計算列を作成します。
PriceOfCurrentProductは現在の行のUnit Priceの値で、FILTER内ではすべての製品をスキャンしています。


# Page. 21

![Page Image](https://bcdn.docswell.com/page/L73N4DN575.jpg)

同じテーブルのネストされた行コンテキスト


# Page. 22

![Page Image](https://bcdn.docswell.com/page/87DWQPWYJG.jpg)

同じテーブルのネストされた行コンテキスト
UnitPriceRanDense =
VAR
PriceOfCurrentProduct = &#039;Product&#039;[Unit Price]
VAR
商品ではなく、現在の価格よりも高い価格をカウン
HigherPrices =
トすると、同じ価格の商品は1つにまとめられる
FILTER(
VALUES( &#039;Product&#039;[Unit Price] ) ,
&#039;Product&#039;[Unit Price] &gt; PriceOfCurrentProduct
)
RETURN
COUNTROWS( HigherPrices ) + 1
ランク付けの方法を、同順位が複数あっても次の順位値は＋１になるようにします。


# Page. 23

![Page Image](https://bcdn.docswell.com/page/VJP9LN92E8.jpg)

同じテーブルのネストされた行コンテキスト
1位の次は2位


# Page. 24

![Page Image](https://bcdn.docswell.com/page/2EVMQKMXEQ.jpg)

EARLIERを使う
&#039;Product&#039;[UnitPriceRankDense ] =
COUNTROWS(
FILTER(
Values( &#039;Product&#039;[Unit Price] ),
EARIERは、外側の行コン
テキストにアクセスする
&#039;Product&#039;[UnitPrice] &gt; EARLIER( &#039;Product&#039;[ UnitPrice] )
)
) + 1
EARLIERを使用して、FILTERの外側の行コンテキストにアクセスすることがで
きます。ただし、現在は、EARLIERの使用は推奨されていません。変数を使う
方がより読みやすいコードになり、ベストプラクティスになります。


# Page. 25

![Page Image](https://bcdn.docswell.com/page/57GGWQGR7L.jpg)

FILTERを使う
NumOfRedProducts :=
VAR RedProducts =
FILTER(
&#039;Product&#039;,
&#039;Product&#039;[Color] = &quot;Red&quot;
)
RETURN
COUNTROWS( RedProducts )
FILTERはテーブル（フィルタコンテキストによって既にフィルタリングされている）をスキャンするイテレータで、
フィルタリング条件に従って、そのテーブルのサブセットを返します。


# Page. 26

![Page Image](https://bcdn.docswell.com/page/4EQX3KXY7P.jpg)

FILTERを使う２ スライサーの追加
左は、スライサーとメジャーともにRedをフィルターしており、ブランドごとのRed色の製品の数が表示されている。
右では、スライサーはAzureをフィルターしており、メジャーでRedの個数を求めても存在しない。


# Page. 27

![Page Image](https://bcdn.docswell.com/page/KJ461P6Z71.jpg)

ALLを使う
NumOfRedProducts :=
VAR RedProducts =
FILTER(
ALL( &#039;Product&#039; ),
&#039;Product&#039;[Color] = &quot;Red&quot;
)
RETURN
COUNTROWS( RedProducts )
FILTER は Product をイテレートしません。
代わりに ALL(Product) をイテレートして、すべてがRedの製品数の合計値になります。


# Page. 28

![Page Image](https://bcdn.docswell.com/page/LE1VG9VD7G.jpg)

ALLを使う
テーブルのBrandの項目は、スライサーでフィルターされた色のあるブランド名が表示されますが、
値は全てRed色の製品数の合計数になります。


# Page. 29

![Page Image](https://bcdn.docswell.com/page/GEWLKQL872.jpg)

リレーションシップ
◆ RELATEDは、リレーションシップの多数側のテーブルの行コンテキストが必要。
◆ RELATEDTABLEは、現在イテレートしているテーブルと関係のある多数側のテー
ブルの行をすべて返す。
◆ いずれもリレーションの連鎖する先をたどることができる。
◆ リレーションの連鎖は、全ての関係が同じタイプである必要がある。
◆ ただし、1対1のリレーションは、1対多、多対1と同時に使用できる。
◆ クロスフィルターの方向に注意。双方向フィルターは特別な場合を除いて使う
べきではない。


# Page. 30

![Page Image](https://bcdn.docswell.com/page/47ZMZWM9E3.jpg)

購入履歴から顧客の平均年齢を計算する
Sales[Customer Age] =
// 購入履歴に顧客の年齢を示す計算列を作成する
DATEDIFF (
RELATED ( Customer[Birth Date] ),
Sales[Order Date],
YEAR
)


# Page. 31

![Page Image](https://bcdn.docswell.com/page/YJ6NZGNDJV.jpg)

購入履歴から顧客の平均年齢を計算する
Avg Customer Age := AVERAGE ( Sales[Customer Age] )
このメジャーでは、購入履歴ごとの年齢を足し上げて平均を出しているので、同じ
顧客が複数回購入した場合、正しい値にならない。


# Page. 32

![Page Image](https://bcdn.docswell.com/page/GJ55WV58J4.jpg)

購入履歴から顧客の平均年齢を計算する
Avg Customer Age :=
AVERAGEX (
DISTINCT ( Sales[Customer Age] ),
Sales[Customer Age]
)
このメジャーでは、違う顧客でも年齢が同じ場合1つにまとめられてしまい、正し
い値にならない。


# Page. 33

![Page Image](https://bcdn.docswell.com/page/LE3N4DNGE5.jpg)

購入履歴から顧客の平均年齢を計算する
Avg Customer Age :=
AVERAGEX (
DISTINCT ( Sales[CustomerKey] ),
Sales[Customer Age]
)
このメジャーは、AVERAGEXの第1引数で顧客が一意になるSales[CustomerKey]
の1列だけ含まれる行コンテキストが生成されるため、第 2引数のSales[Customer
Age]は計算できない。


# Page. 34

![Page Image](https://bcdn.docswell.com/page/8EDWQPWN7G.jpg)

購入履歴から顧客の平均年齢を計算する
Avg Customer Age :=
AVERAGEX (
SUMMARIZE (
Sales,
Sales[CustomerKey],
Sales[Customer Age]
),
Sales[Customer Age]
)
SUMMARIZEは、2つの列のユニークな組み合わせを生成することができる。


# Page. 35

![Page Image](https://bcdn.docswell.com/page/V7P9LN9NJ8.jpg)

購入履歴から顧客の平均年齢を計算する
Avg Customer Age :=
VAR CustomersAge =
SUMMARIZE (
Sales,
Sales[CustomerKey],
Sales[Customer Age]
)
RETURN
AVERAGEX (
CustomersAge,
Sales[Customer Age]
)
変数を使用して計算を分割できます。AVERAGEX関数の第2引数でSalesテーブル
への参照していることに注意してください。変数にテーブルを入れることはできます
が、参照として利用することはできません。


# Page. 36

![Page Image](https://bcdn.docswell.com/page/2JVMQKMYJQ.jpg)

まとめ
➢ 評価コンテキストには、フィルタコンテキストと行コンテキストの２つがある。
➢ 数式の理解には2つの評価コンテキストを考慮する必要がある。
➢ DAXは、計算列に対して行コンテキストを自動的に作成します。
➢ テーブル式の結果であるテーブルをイテレートする場合、行コンテキストには
テーブル式が返す列のみが含まれます。
➢ Power BIでは、行、列、スライサー、フィルターにフィールドを使用すると、フィル
ターコンテキストが作成されます。
➢ CALCULATEを使用してプログラム的にフィルタコンテキストを作成することもできます。
➢ 行コンテキストは、リレーションシップを通じて自動的に伝搬しません。
➢ フィルタコンテキストはモデルをフィルタリングして、そのクロスフィルタの方向に
従ってリレーションシップを使用します。


