22
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Microsoft Power BIAdvent Calendar 2022

Day 5

集計列追加のベストプラクティス🤔~とはいえ例外だってあるぞ~

Last updated at Posted at 2022-12-04

はじめに

すこし複雑なメジャーを記述しようとすると、避けては通れないテーブル操作関数。主要なSUMMARIZEADDCOLUMNSSUMMARIZECOLUMNSなどを研究してみます。

テーブル操作関数シリーズ

続きものです。

  1. SUMMARIZE関数の研究~集計列の追加はなぜ非推奨なのか🤔~
  2. ADDCOLUMNS関数の研究~集計列追加のベストプラクティス🤔~
  3. 集計列追加のベストプラクティス🤔~とはいえ例外だってあるぞ~
  4. SUMMARIZECOLUMNS関数の研究~SUMMARIZE関数は非推奨?🤔~
  5. GROUPBY関数の研究🤔~基本動作確認編~

DAXクエリ&DAX.do

今回の検証はDAX.do上でDAXクエリを書いて検証していきます。
DAXクエリがわからない方は先にこの記事を読んで、DAX.doで少し触ってからのほうが理解が進むでしょう。

DAXクエリについてはこちらの記事を参照してください。

参考記事

復習

集計列追加のベストプラクティス

ADDCOLUMNS(
    SUMMARIZE( <table>, <group by column> ),
    <column_name>, CALCULATE( <expression> )
)

DAX.doで例を作成すると、こんな感じ。

EVALUATE
ADDCOLUMNS (
    SUMMARIZE ( Sales, 'Product'[Brand] ),
    "SalesAMT", CALCULATE ( SUMX ( 'Sales', Sales[Net Price] * Sales[Quantity] ) )
)

image.png

例外を検証してみる

参考記事をもとにDAXを実行してみます。GENERATE関数とTOPN関数で各製品ごとに売上上位2名の売上金額を集計しています。これはフィルターコンテキストを操作していませんし、正しい数字が計算されています。

EVALUATE
SUMMARIZE (
    GENERATE ( 'Product', TOPN ( 2, Customer, [Sales Amount] ) ),
    'Product'[Category],
    Customer[Country],
    "Margin", [Margin]
)
ORDER BY [Margin] DESC

image.png

集計列追加のベストプラクティスを適用してみる🤔

上記DAXの集計列部分をベストプラクティスに沿ってADDCOLUMNS関数を追加してみます。

EVALUATE
ADDCOLUMNS (
    SUMMARIZE (
        GENERATE ( 'Product', TOPN ( 2, Customer, [Sales Amount] ) ),
        'Product'[Category],
        Customer[Country]
    ),
    "Margin", [Margin]
)
ORDER BY [Margin] DESC

すると結果は先程よりも大きい数字が得られ、計算結果が期待した数字ではありません🤔

image.png

参考記事を読むに、SUMMARIZE関数の中で計算している製品ごとの売上上位2名の売上金額ADDCOLUMNS関数でくるんだときに、集系列に対して適切にフィルターコンテキストが伝わらないことが原因のよう。

image.png

ということは🤔いま出た結果はSUMMARIZE関数の中で計算しているものをなくしたものと結果が合うはず。GENERATE関数以下の部分を削除し、'Sales'テーブルに置き換え、DAXクエリを実行してみます。

EVALUATE
ADDCOLUMNS (
    SUMMARIZE (
        'Sales',
        'Product'[Category],
        Customer[Country]
    ),
    "Margin", [Margin]
)
ORDER BY [Margin] DESC

ベストプラクティスを適用したときと同様の数字を得ることができました。やはり、SUMMARIZE関数の元テーブルで計算したフィルターコンテキストがADDCOLUMNS関数で追加した集計列に届いていません。

image.png

正しい結果にするには💪

SUMMARIZE関数の中で計算している製品ごとの売上上位2名の売上金額を変数で定義します。そして、ADDCOLUMNS関数で集計列を追加する際に、CALCULATE関数でくくり、KEEPFILTERS関数でフィルターコンテキストを保持して[Margin]メジャーの評価時に使用します。

DEFINE
    VAR __producttop2customer =
        GENERATE ( 'Product', TOPN ( 2, Customer, [Sales Amount] ) )

EVALUATE
ADDCOLUMNS (
    SUMMARIZE ( __producttop2customer, Product[Category], Customer[Country] ),
    "Margin", CALCULATE ( [Margin], KEEPFILTERS ( __producttop2customer ) )
)
ORDER BY [Margin] DESC

すると、ようやく正しい数字がでました💪 ただ…ややこしい!
参考記事によるとパフォーマンスも良くないらしい。

image.png

集計列追加のベストプラクティスの例外

集計列追加のベストプラクティスの例外

SUMMARIZE関数で追加した集計列をADDCOLUMNS関数に置き換えないほうがいいときは、

  • SUMMARIZE関数で使用されるテーブルに特定のフィルターがある場合
  • 集計列で、メジャーなどSUMMARIZE関数でまとめたテーブルにない項目を使用するとき

ということ。(だと理解した。)

うーむ難しい🤔

まとめ

手を動かしながら検証をしていくと理解が進む。記事を読んだだけじゃあわからない。だけど、正しく理解ができているのか、正しく言語化できているのか自信がない😅
少しでも興味をもってくれた人は参考記事も必ず読んでくださいね!

改めて参考記事

22
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?