前回、PowerBI/PowerPivot(以下、総称してDAXと呼びます)におけるコンテキスト(行コンテキスト、フィルターコンテキスト)のALL関数について書きました。
今回は、テーブルのリレーションシップを跨いでコンテキストがどのように影響を及ぼすかについて書いてみたいと思います。
行コンテキストのリレーション間伝播
例として、下記のようなテーブル構成を考えてみます。
この場合において、売上明細テーブルに計算列を作成し、下記のようなDAX式を定義してみます。
[予実比較] = 売上明細[販売単価] - 商品[定価]
売上明細テーブルで行コンテキストが評価されるため、売上明細テーブルを反復処理します。この場合、商品テーブルは参照できません。エラーになります。
しかし、よく考えてみると、不思議です。売上明細テーブルから商品テーブルへのリレーションは一方向で、[商品]1:[売上明細]多の関係です。売上明細から商品は一意に特定できるので、参照可能ではないかとも思えます。
DAXではこのような場合、RELATED関数を使用して明示的にリレーションの参照を指示する必要があります。下記のように変更すると、うまくいきます。
[予実比較] = 売上明細[販売単価] - RELATED(商品[定価])
RELATED関数はリレーションシップの(1対多)関係のうち、「多」側のテーブルで行コンテキストが評価される場合に機能します。「多」側テーブルから、関係テーブルを参照できます。
その逆はどうでしょうか。逆の場合はデータを一意に特定できず、複数の値が返されるためRELATED関数ではうまく機能しません。このような場合にはRELATEDTABLE関数を使用します。
[販売数] = COUNTROWS(RELATEDTABLE('売上明細'))
RELATEDTABLE関数は、指定されたリレーションシップテーブルにおいて、関連する行を全て返します。上記の式は、ヒットした行をカウントしています。
フィルターコンテキストのリレーション間伝播
行コンテキストでは明示的に関数によってリレーションの参照を行う必要がありました。フィルターコンテキストの場合は、いわば自動的に参照します。参照が可能な場合にのみ参照する、とも言えます。
しかし、難しく考えることはありません。基本的に、リレーションダイアグラムの矢印方向に沿ってのみ参照が可能であるという理解で問題ありません。
例えば、[顧客]テーブルの[顧客ID]を行要素として表示している際に、
[顧客別販売量] = COUNTROWS(売上明細)
として販売量をだすことは可能です。なぜなら、顧客テーブルから売上明細への矢印方向に従っているからです。上記の例では他にも[商品]から[売上明細]への参照も同様に有効です。
逆の参照が行われた場合(例えば、売上明細から顧客テーブルへの参照が行われた場合)には全数が返されます(つまり、全顧客数が返されることになります) 適切な参照が行われず、列全体が返されています。
また、フィルターコンテキストも行コンテキストの場合と同じように、関係をいくつも跨いでいくことができます。リレーションシップの矢印方向に従った形であれば、ホップ数に関係なく参照することができます。