1.4K Views
March 26, 23
スライド概要
The Definitive Guide to DAX Chapter 4 勉強用スライド
The Definitive Guide to DAX Chapter 4 Understanding evaluation contexts (評価の背景を理解する)
この章で学ぶこと
この章で学ぶこと
この章で学ぶこと
この章で学ぶこと
この章で学ぶこと
計算列で以下の式の結果はどうなりますか。 Sales[SumOfSalesQuantity] = SUM(Sales[Quantity]) 1.その行のQuantityの値、つまり各行で異なる値。 2.すべての行のQuantityの合計、つまり、全ての行で同じ値。 3.計算列の内部でSUMを使用することはできません。
計算列で以下の式の結果はどうなりますか。 Sales[SumOfSalesQuantity] = SUM(Sales[Quantity]) 1.その行のQuantityの値、つまり各行で異なる値。 2.すべての行のQuantityの合計、つまり、全ての行で同じ値。 3.計算列の内部でSUMを使用することはできません。
計算列で以下の式の結果はどうなりますか。 Sales[SumOfSalesQuantity] = SUM(Sales[Quantity])
計算列で以下の式の結果はどうなりますか。 Sales[SumOfSalesQuantity] = SUM(Sales[Quantity]) ➢ この数式は、「現在のフィルタコン テキストで表示されているすべて の量の合計」を意味します。 ➢ この場合、フィルタコンテキストが 存在しないため、テーブル全体を 計算します。
以下のメジャーの結果はどうなりますか。 GrossMargin% = ( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost] 1.この式は正しく動作します。 2.エラーです。この式は書くべきではありません。 3.数式を定義することはできますが、レポートで使用するとエラーが 返されます。 。
以下のメジャーの結果はどうなりますか。 GrossMargin% = ( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost] 1.この式は正しく動作します。 2.エラーです。この式は書くべきではありません。 3.数式を定義することはできますが、レポートで使用するとエラーが 返されます。 。
以下のメジャーの結果はどうなりますか。 GrossMargin% = ( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost]
以下のメジャーの結果はどうなりますか。 GrossMargin% = ( Sales[Net Price] – Sales[Unit Cost] ) / Sales[Unit Cost] ➢ メジャーは自動的に行コンテキスト が発生しない。 ➢ アグリゲータなしで値を取得しよう としているが、どの行に対して計算 を行うか検出する方法がない。
イテレータで行コンテキストを使用する SUMX( Sales, Sales[Net Price] * 1.1 ) ➢ 最初のパラメータ Sales は、呼び出し元からのコンテキストを使用して評価され る。 ➢ 2番目のパラメータは、外部コンテキストと新しく作成された行コンテキストの両 方を使用して評価される。
イテレータで行コンテキストを使用する 既存のコンテキストで最初のパラメータを評価し、スキャンする行を決定する。 前のステップで評価した各行に対して、新しい行コンテキストを作成する。 テーブルをイテレートし、既存のコンテキストと新しく作成された行コンテキストで2番目のパラメータを評価する。 前のステップで計算された値を集計する。
行コンテキストが存在するケース ➢計算列のDAX式が評価されるとき ➢イテレータ関数を使用した時
イテレータ関数とは ➢ SUMX、AVERAGEX、MAXXなど、最後にXがつく関数 ➢ ADDCOLUMNS ➢ FILTER
異なるテーブルのネストされた行コンテキスト SUMX( 'Products Category', SUMX( RELATEDTABLE( 'Product' ) SUMX( RELATEDTABLE( 'Sales' ) Sales[Quantity] * 'Product'[Unit Price] * 'Product Category'[Discount] ) ) ) 3つのネストしたイテレータが含まれており、3つのテーブルをスキャンしている。
同じテーブルのネストされた行コンテキスト 'Product'[UnitPriceRank] = Productの現在の行の値 VAR PriceOfCurrentProduct = 'Product'[Unit Price] VAR MoreExpensiveProducts = FILTERでイテレートされたProductの値 FILTER( 'Product', 'Product'[Unit Price] > PriceOfCurrentProduct ) RETURN COUNTROWS( MoreExpensiveProducts ) + 1 RANKXを使用しないで製品の価格が高いものからランク付けした計算列を作成します。 PriceOfCurrentProductは現在の行のUnit Priceの値で、FILTER内ではすべての製品をスキャンしています。
同じテーブルのネストされた行コンテキスト
同じテーブルのネストされた行コンテキスト UnitPriceRanDense = VAR PriceOfCurrentProduct = 'Product'[Unit Price] VAR 商品ではなく、現在の価格よりも高い価格をカウン HigherPrices = トすると、同じ価格の商品は1つにまとめられる FILTER( VALUES( 'Product'[Unit Price] ) , 'Product'[Unit Price] > PriceOfCurrentProduct ) RETURN COUNTROWS( HigherPrices ) + 1 ランク付けの方法を、同順位が複数あっても次の順位値は+1になるようにします。
同じテーブルのネストされた行コンテキスト 1位の次は2位
EARLIERを使う 'Product'[UnitPriceRankDense ] = COUNTROWS( FILTER( Values( 'Product'[Unit Price] ), EARIERは、外側の行コン テキストにアクセスする 'Product'[UnitPrice] > EARLIER( 'Product'[ UnitPrice] ) ) ) + 1 EARLIERを使用して、FILTERの外側の行コンテキストにアクセスすることがで きます。ただし、現在は、EARLIERの使用は推奨されていません。変数を使う 方がより読みやすいコードになり、ベストプラクティスになります。
FILTERを使う NumOfRedProducts := VAR RedProducts = FILTER( 'Product', 'Product'[Color] = "Red" ) RETURN COUNTROWS( RedProducts ) FILTERはテーブル(フィルタコンテキストによって既にフィルタリングされている)をスキャンするイテレータで、 フィルタリング条件に従って、そのテーブルのサブセットを返します。
FILTERを使う2 スライサーの追加 左は、スライサーとメジャーともにRedをフィルターしており、ブランドごとのRed色の製品の数が表示されている。 右では、スライサーはAzureをフィルターしており、メジャーでRedの個数を求めても存在しない。
ALLを使う NumOfRedProducts := VAR RedProducts = FILTER( ALL( 'Product' ), 'Product'[Color] = "Red" ) RETURN COUNTROWS( RedProducts ) FILTER は Product をイテレートしません。 代わりに ALL(Product) をイテレートして、すべてがRedの製品数の合計値になります。
ALLを使う テーブルのBrandの項目は、スライサーでフィルターされた色のあるブランド名が表示されますが、 値は全てRed色の製品数の合計数になります。
リレーションシップ ◆ RELATEDは、リレーションシップの多数側のテーブルの行コンテキストが必要。 ◆ RELATEDTABLEは、現在イテレートしているテーブルと関係のある多数側のテー ブルの行をすべて返す。 ◆ いずれもリレーションの連鎖する先をたどることができる。 ◆ リレーションの連鎖は、全ての関係が同じタイプである必要がある。 ◆ ただし、1対1のリレーションは、1対多、多対1と同時に使用できる。 ◆ クロスフィルターの方向に注意。双方向フィルターは特別な場合を除いて使う べきではない。
購入履歴から顧客の平均年齢を計算する Sales[Customer Age] = // 購入履歴に顧客の年齢を示す計算列を作成する DATEDIFF ( RELATED ( Customer[Birth Date] ), Sales[Order Date], YEAR )
購入履歴から顧客の平均年齢を計算する Avg Customer Age := AVERAGE ( Sales[Customer Age] ) このメジャーでは、購入履歴ごとの年齢を足し上げて平均を出しているので、同じ 顧客が複数回購入した場合、正しい値にならない。
購入履歴から顧客の平均年齢を計算する Avg Customer Age := AVERAGEX ( DISTINCT ( Sales[Customer Age] ), Sales[Customer Age] ) このメジャーでは、違う顧客でも年齢が同じ場合1つにまとめられてしまい、正し い値にならない。
購入履歴から顧客の平均年齢を計算する Avg Customer Age := AVERAGEX ( DISTINCT ( Sales[CustomerKey] ), Sales[Customer Age] ) このメジャーは、AVERAGEXの第1引数で顧客が一意になるSales[CustomerKey] の1列だけ含まれる行コンテキストが生成されるため、第 2引数のSales[Customer Age]は計算できない。
購入履歴から顧客の平均年齢を計算する Avg Customer Age := AVERAGEX ( SUMMARIZE ( Sales, Sales[CustomerKey], Sales[Customer Age] ), Sales[Customer Age] ) SUMMARIZEは、2つの列のユニークな組み合わせを生成することができる。
購入履歴から顧客の平均年齢を計算する Avg Customer Age := VAR CustomersAge = SUMMARIZE ( Sales, Sales[CustomerKey], Sales[Customer Age] ) RETURN AVERAGEX ( CustomersAge, Sales[Customer Age] ) 変数を使用して計算を分割できます。AVERAGEX関数の第2引数でSalesテーブル への参照していることに注意してください。変数にテーブルを入れることはできます が、参照として利用することはできません。
まとめ ➢ 評価コンテキストには、フィルタコンテキストと行コンテキストの2つがある。 ➢ 数式の理解には2つの評価コンテキストを考慮する必要がある。 ➢ DAXは、計算列に対して行コンテキストを自動的に作成します。 ➢ テーブル式の結果であるテーブルをイテレートする場合、行コンテキストには テーブル式が返す列のみが含まれます。 ➢ Power BIでは、行、列、スライサー、フィルターにフィールドを使用すると、フィル ターコンテキストが作成されます。 ➢ CALCULATEを使用してプログラム的にフィルタコンテキストを作成することもできます。 ➢ 行コンテキストは、リレーションシップを通じて自動的に伝搬しません。 ➢ フィルタコンテキストはモデルをフィルタリングして、そのクロスフィルタの方向に 従ってリレーションシップを使用します。