Power BI- メジャーの中に埋め込んだメジャーがどう機能しているかなど
今日、少し行き詰ってリフレッシュしようと思い、Power BI CommunityのGalleryを見ていると、面白いレポートがありました。そこには何個か疑問に思っていたことがクイズ形式で出題されていたので、備忘のためにここに書いておきます
全ての問題に共通する前提
①「Colorテーブル」:ディメンションテーブル。BlackとWhiteの2色が定義されているテーブル
②「Numbersテーブル」:ファクトテーブル。色と数の組み合わせ。
※留意するべき点は、1行目と3行目は同じレコードということです。
③ 2つのテーブルの間にはリレーションが1つ設定されています。
④ あらかじめメジャーが一つ作成されています。
//所与のメジャー
Total Quantity = SUM ( Numbers[Quantity])
至ってシンプルな、「Numbersテーブル」のQuantity列の合計を計算するというものです。
Q1:COUNTROWS()関数で「列」の「組み合わせ(場合の数)」を計算する方法
Q1. 所与の前提のもとで、次の2つのメジャーAとBは、同じ結果を返すでしょうか?
Measure A = COUNTROWS ( ALL ( Numbers ) )
Measure B = COUNTROWS ( ALL ( Numbers[Color], Numbers[Quantity] ) )
まず Measure Aについて、これは、「Numbers」テーブルにかかっているフィルターを全て外して(ALL関数)行数をカウントする、という計算式ですので、答えは3行です。(こっちはすぐにわかる)
次に、Measure Bについて、こっちが問題です。
「Numbers」テーブルの「Color」列と、「Quantity」列の両方にALL()をかけていると思いきや、ALL()の中に、2つの列が含まれています。
この場合、「ALL ( Numbers[Color], Numbers[Quantity] )」の式は、2列の各行を見て、重複のない列の組み合わせを答えとして返します。
従って、「ALL ( Numbers[Color], Numbers[Quantity] )」の返してくる答えは、次のようなテーブルになっています。
従って、Measure Bの返す答えは、2行になります。
以上から、
Measure A = 3
Measure B = 2
となって、答えは、Falseとなります。
Q2:メジャーの中で複数のフィルターをかけると、フィルターは上書きされる例
Q2: 次のメジャーはどんな答えを返すでしょうか?
Something =
CALCULATE (
CALCULATE ( VALUES ( Color[Color]), Color[Color] = "Black" ),
Color[Color] = "White"
)
このメジャーはCALCULATE関数が入れ子になっています。
ポイントは、メジャーの中で、DAX式が引数として使用されている点です。(メジャーの外で定義されたメジャーを引数にしているわけではないということ)
この場合、一番外側のCALCULATEは、"Black"でColorを絞ればいいのか、"White"でColorを絞ればいいのか分からなくなりそうですが、
今回参照した問題による解説は、「一番内側のフィルターで上書きされる」ということです。
別の言い方をすると、上記のメジャーは次の記載と同じことを指定していることになります。
Something =
CALCULATE ( VALUES ( Color[Color]), Color[Color] = "Black" )
「上書きされる」。長めのメジャーを書くときは知っておくべきDAXの挙動ですね。
(補足)この記事を最初に書いてから読み返していると、上書きされる(override)という表現はミスリードしているんじゃないかなと思いました。
実際DAX式の中で起こっていることは、上書きされるのではなく、関数の中の一番内側の引数から計算されていくので、「関数の計算結果として指定された引数」(今回の場合は「CALCULATE ( VALUES ( Color[Color]), Color[Color] = "Black" )」ですね)が内側の引数からどんどん固定値に置き換えられていくため、今回の例では一番外側に設定された「Color[Color] = "Black"」というフィルターが機能しなくなっている、という説明の方が正しいと思います。(関数の中で起こっている処理の順番は、エクセルと同じです。エクセルで検証する場合は、「数式の検証」という機能が「数式」タブの中にあるので、で1ステップずつ計算過程を見ていくと、そのように計算されていることが目で追えます)
(関数の中で起こっている処理の順番は、エクセルと同じです。エクセルで検証する場合は、「数式の検証」という機能が「数式」タブの中にあるので、で1ステップずつ計算過程を見ていくと、そのように計算されていることが目で追えます)
Q3. メジャーでDAX関数を直接記述する場合と、メジャーを引数とする場合で、処理結果が変わる例(SUMX)
Q3: 次の2つのメジャーは同じ結果を返すと思いますか?
//所与のメジャー
Total Quantity = SUM ( Numbers[Quantity] )
//2つのメジャー
Measure A = SUMX ( Numbers, [Total Quantity] )
Measure B = SUMX ( Numbers, Numbers[Quantity] )
以前、SUMX()に関して記載した記事でも同様のことを記載しましたが、まず、Measure B を先に書くと、これはいわゆる「SUMX()を使う意味ないやん」といわれるパターンです。
すなわち、上記のMeasure B は次の書き方をすることと何ら変わりません。
Measure B = SUM ( Numbers[Quantity] )
よって、Measure B の答えは、5ですね。
次に、Measure A です。
SUMX関数は、第1引数で指定したテーブル(ないし、列)を1行ずつ、第2引数で指定した関数やメジャーで処理していきます。
従って、Measure A が行っている処理を1ステップずつ記載すると、、
① 1行目の処理で、Black/1の組み合わせのテーブル(2行ありますよね)を作成し、合計するので、2 を返します。
② 2行目の処理で、White/3の組み合わせのテーブル(これは1行しかないテーブルになります)を作成し、合計するので、3を返します。
③ 3行目の処理で、再びBlack/1の組み合わせのテーブル(①と同じテーブル)を作成し、合計するので、2を返します。
④ 最後に、①~③の合計をするので、2+3+2=7 がMeasure B の答えになります。
以上から、
Measure A = 5
Measure B = 7
となり、答えはFalseになります。
Q4. メジャーの中に、別のメジャーを変数として指定すると、埋め込まれたメジャーにはフィルターは上書きされない例
Q4. Colorテーブルにフィルターをかけていない場合、次の2つのメジャーは同じ答えを返しますか?
//所与のメジャー
Total Quantity = SUM ( Numbers[Quantity] )
//2つのメジャー
Measure A = CALCULATE ( [Total Quantity], Color[Color] = "White" )
Measure B =
VAR TotalQuantity = [Total Quantity]
Return
CALCULATE ( TotalQuantity, Color[Color] = "White" )
Measure A は、Colorを"White"に絞って、メジャー[Total Quantity]を計算するというものだから、Numbersテーブルは、まずWhite/3の1行にフィルターがかけられて、そのフィルターがかかったテーブルに対して[Total Quantity] が計算されるので、答えは3になる。(ここは、特に疑問を持たなくてもいいところ)
Measure Bは、変数として TotalQuantityを最初に定義しています。
メジャーは上から一度だけ処理していくので、この場合、まずTotalQuantityという変数に、処理された[Total Quantity]がぶち込まれます。この際、[Total Quantity]はフィルターのかかっていないNumbersテーブル(※所与の条件)で処理を実行するので、変数TotalQuantityは5になります。(先ほどの「上書き」の例と混同してはいけないのは、この例の場合、「上書き」以前の問題で、固定値に置き換わってしまったので、上書きの仕様がないということです)
従って、CALCULATE関数は、変数であるTotalQuantityを、Color[Color] = "White" でフィルターすることができず、答えは5になります。
以上になります。
リンク先にはもう1問、Question 5がありますが、なんというか、、当たり前すぎるような気がしたのでここでは割愛します。
この記事が気に入ったらサポートをしてみませんか?