SUMMARIZE 関数で集計列を追加しない理由


グループ化したテーブルを返す比較的よく利用するテーブル関数ではあるのだけど、使用する範囲を限定した方が得策なんだよねと。SUMMARIZE function (DAX) - DAX | Microsoft Docs で集計した結果を得るのはやめようよという話。メジャーの記述に含めているときは要注意なのである。

メジャーなど DAX をどう記述するとかお伝えする仕事をしていますが、

  • 引き続き利用していくことはご自由に。ただ、デバッグの手間が増えるだけです。
  • 期待する結果を得ていない、かつ、それに気づかないことが最悪のケースです。

ということを機会があるたび、そう述べています。要はおススメできない。で、どれぐらいのインパクトなのかというと、コードを眺め始めた段階で、もし該当の記述が確認できてしまったらその場で修正する対象でもある。

なにが起こるか観察すること大事

担当者ごとの売上集計ができるデータモデルで観察する。

メジャーを記述した。

メジャー
DEFINE
    MEASURE '受注'[受注額] =
        SUMX( '受注', '受注'[数量] * '受注'[単価] )
    MEASURE '受注'[受注額(所属)] =
        CALCULATE( [受注額], ALL( '担当'[氏名] ) )

期待する結果
SUMMARIZECOLUMNS function (DAX) - DAX | Microsoft Docs を使った。各行では '担当'[氏名] ごとの集計と'担当'[所属] ごとの集計を得られる。SUMMARIZECOLUMNS 関数は比較的新しい関数だし、手抜かりなく結果を得ることができるでしょう。記述した内容と得られた結果が自然で当然の結果と思える。

DAXクエリ
EVALUATE
SUMMARIZECOLUMNS(
    '担当'[所属], '担当'[氏名],
    "受注額", [受注額],
    "受注額(所属)", [受注額(所属)]
)
------------------
所属  氏名  受注額   受注額(所属)
"東京本社"  "森上 偉久馬"  3810350 13718950
"東京本社"  "葛城 孝史" 4742500 13718950
"東京本社"  "加藤 泰江" 5166100 13718950
"大阪支社"  "川村 匡"    3287400 8457780
"大阪支社"  "松沢 誠一" 2456200 8457780
"大阪支社"  "成宮 真紀" 2714180 8457780
"北九州支社"   "山本 雅治" 2449200 7005500
"北九州支社"   "青木 俊之" 2329000 7005500
"北九州支社"   "小川 さよ子"  2227300 7005500

起こりえること
期待する結果が得られない、ただ、それだけ。'担当'[所属] ごとの集計を得られない。関数としては仕様通りに集計しているのだけど、思っていたのと結果が違うよねとなるわけです。一目瞭然のケースを挙げているけど、もしかすると微細な違いにしかならないでデータやデータモデルであったときどうしてますか?って話ですよ。

DAXクエリ
EVALUATE
SUMMARIZE(
    '担当', '担当'[所属], '担当'[氏名],
    "受注額", [受注額],
    "受注額(所属)", [受注額(所属)]    
)
------------------
所属  氏名  受注額   受注額(所属)
"東京本社"  "森上 偉久馬"  3810350 3810350
"東京本社"  "葛城 孝史" 4742500 4742500
"東京本社"  "加藤 泰江" 5166100 5166100
"大阪支社"  "川村 匡"    3287400 3287400
"大阪支社"  "松沢 誠一" 2456200 2456200
"大阪支社"  "成宮 真紀" 2714180 2714180
"北九州支社"   "山本 雅治" 2449200 2449200
"北九州支社"   "青木 俊之" 2329000 2329000
"北九州支社"   "小川 さよ子"  2227300 2227300

ではどうするか
期待する結果が得られない可能性を考え続けるのは無駄だから SUMMARIZE 関数で集計列を追加しなけれければよいのだ。ADDCOLUMNS function (DAX) - DAX | Microsoft Docs を使う。SUMMARIZECOLUMNS 関数は メジャーの記述に使用できない。

DAXクエリ
EVALUATE
ADDCOLUMNS(
    SUMMARIZE( '担当', '担当'[所属], '担当'[氏名] ),
    "受注額", [受注額],
    "受注額(所属)", [受注額(所属)]
)
------------------
所属  氏名  受注額   受注額(所属)
"東京本社"  "森上 偉久馬"  3810350 13718950
"東京本社"  "葛城 孝史" 4742500 13718950
"東京本社"  "加藤 泰江" 5166100 13718950
"大阪支社"  "川村 匡"    3287400 8457780
"大阪支社"  "松沢 誠一" 2456200 8457780
"大阪支社"  "成宮 真紀" 2714180 8457780
"北九州支社"   "山本 雅治" 2449200 7005500
"北九州支社"   "青木 俊之" 2329000 7005500
"北九州支社"   "小川 さよ子"  2227300 7005500

集計列のメジャーを定義していない場合は、CALCULATE 関数でラップすると期待する結果を得られる。このあたりは、テーブルへの計算列の追加で学んでいるはずですよ。

DAXクエリ
EVALUATE
ADDCOLUMNS(
    SUMMARIZE( '担当', '担当'[所属], '担当'[氏名] ),
    "# of Sales ID", COUNTROWS( VALUES( '受注'[受注ID] ) ),
    "# of Sales ID (Correct)", CALCULATE( COUNTROWS( VALUES( '受注'[受注ID] ) ) )
)
------------------
所属  氏名  # of Sales ID   # of Sales ID (Correct)
"東京本社"  "森上 偉久馬"  300 39
"東京本社"  "葛城 孝史" 300 46
"東京本社"  "加藤 泰江" 300 46
"大阪支社"  "川村 匡"    300 32
"大阪支社"  "松沢 誠一" 300 25
"大阪支社"  "成宮 真紀" 300 29
"北九州支社"   "山本 雅治" 300 27
"北九州支社"   "青木 俊之" 300 33
"北九州支社"   "小川 さよ子"  300 23

思ったこと🙄

DAX 謎マナーではない。常に正確な結果を得るための習慣なのである。
そういえば、CALCULATE 関数 は 適用するフィルタを変更する効果が得ることができるのであって、フィルタを変更する関数ではないんだよね。ってこと気付いてほしいなと思ったなど。

その他