23
6

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 3

SUMMARIZE関数の研究~集計列の追加はなぜ非推奨なのか🤔~

Last updated at Posted at 2022-12-02

はじめに

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

本記事はSUMMARIZE関数編です。

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

続きものです。

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

参考記事

参考…というかほぼパクリ検証ですので、基本的にはSQLBIの下記記事を読むのをおすすめします😁

SUMMARIZE関数の文法を調べる

DAX GUIDEでSUMMARIZE関数の文法を確認します。

image.png

ベーステーブルを最初に指定して、その後はグループ化したい列名を入れていきます。またその後、,では集計列を追加することができます。

非推奨…?

image.png

しかしその下の説明文を読むと、パラメーターのNameExpressionのところには NOT RECOMMENDED(非推奨) と書いてあります。

なぜだ🤔

検証開始

使用データ

Power BI Desktopの「New Table」で下記DAXを入力。
簡単なテーブルを作成し、検証していきます。

Sales_Single_Table = 

DATATABLE (
    "プロダクト", STRING,
    "カラー", STRING,
    "数量", INTEGER,
    "売上", DOUBLE,
    {
        { "バイク", "レッド", 1, 100 },
        { "シャツ", "レッド", 2, 200 },
        { "シャツ", "グリーン", 2, 200 },
        { "バイク", "グリーン", 3, 300 },
        { "シャツ", "グリーン", 3, 300 },
        { "バイク", "ブルー", 3, 300 },
        { "シャツ", "ブルー", 4, 400 }
    }
)

image.png

SUMMARIZE関数で集計列を追加してみる

非推奨だとは言われていますが、どうやら、できる。
列を集計することはできており、数字も正しい🤔

SUMMARIZE(
    Sales_Single_Table,
    Sales_Single_Table[カラー],
    "売上", SUM(Sales_Single_Table[売上])
    )

image.png

フィルターを操作してみる

そこで、今度はフィルターを操作して全体の売上を表示する列を作成してみます。
結果の期待値としては、こう。
割合を求めるときにはこういう列をつくるときありますよね。

image.png

方針としてはREMOVEFILTERS関数を使用して、カラー列でかかっている行コンテキストを削除し、合計値1,800を求めていきます。

方針通り、DAXを記載して実行すると…

SUMMARIZE (
    Sales_Single_Table,
    Sales_Single_Table[カラー],
    "売上", SUM ( Sales_Single_Table[売上] ),
    "総売上",
        CALCULATE (
            SUM ( Sales_Single_Table[売上] ),
            REMOVEFILTERS ( Sales_Single_Table[カラー] )
        )
)

結果は、こう。

image.png

むむ?期待した結果と違う🤔500という数字はどこからきた?

どういう処理がなされているのか検証する旅にでます。まず、プロダクト列を追加して、結果をもう少し細かく見てみます。

SUMMARIZE (
    Sales_Single_Table,
    Sales_Single_Table[カラー],
    Sales_Single_Table[プロダクト],
    "売上", SUM ( Sales_Single_Table[売上] ),
    "総売上",
        CALCULATE (
            SUM ( Sales_Single_Table[売上] ),
            REMOVEFILTERS ( Sales_Single_Table[カラー] )
        )
)

image.png

やはり売上列と総売上列の数字は合わない。

SUMMARIZE関数はクラスターを作成する。

参考にした記事をさらに読むと、SUMMARIZE関数はクラスターを作成する…とあります。

引数で指定した列がクラスターヘッダーとなります。
クラスターはクラスターヘッダーを先頭に、テーブル内すべての列を使って作成されます。
そして各クラスターの中で集計し、結果のテーブルが出力されます。

図解すると下記のような感じの計算が行われているらしい。

image.png

ということを前提に、REMOVEFILTERS関数を用いたDAXを書いたときに何が起こっているのか図解してみます。

SUMMARIZE (
    Sales_Single_Table,
    Sales_Single_Table[カラー],
    "総売上",
        CALCULATE (
            SUM ( Sales_Single_Table[売上] ),
            REMOVEFILTERS ( Sales_Single_Table[カラー] )
        )
)
  1. 元のテーブル
  2. 引数[カラー]列を先頭にクラスターが作られる
  3. REMOVEFILTERS関数によりカラー列のフィルターが解除される

という動きをして、レッドを先頭に作成されたクラスターは

  • (“バイク”,1,100)
  • (“シャツ”,2,200)

という2つのフィルターコンテキストをもとに売上列の集計を始めます。

すると、

  • (“シャツ”,2,200)

グリーンクラスターで作成されたクラスターの中にも同じコンテキストの数字があります。

ということで、図で囲んだ赤枠部分をすべて足し上げて、レッドの総売上は500という数字になってしまいます。

image.png

ややこしい

直感的ではない計算方法になってしまうので、ややこしく、計算ミスの温床になってしまいそう。

ではどうしたらいいのか🤔

今、求めたい数字を出すためには、すべての列のフィルターを解除してあげればOKというわけです。

SUMMARIZE (
    Sales_Single_Table,
    Sales_Single_Table[カラー],
    "総売上",
        CALCULATE (
            SUM ( Sales_Single_Table[売上] ),
            REMOVEFILTERS (
                Sales_Single_Table[カラー],
                Sales_Single_Table[プロダクト],
                Sales_Single_Table[数量],
                Sales_Single_Table[売上]
            )
        )
)

REMOVEFILTERS関数ですべての列を指定する場合は、テーブル名だけ書いてあげれば同じ意味になります。

SUMMARIZE (
    Sales_Single_Table,
    Sales_Single_Table[カラー],
    "総売上",
        CALCULATE (
            SUM ( Sales_Single_Table[売上] ),
            REMOVEFILTERS ( Sales_Single_Table )
        )
)

結果は期待した数字になりました。

image.png

この検証はシングルテーブルだということを忘れちゃだめ

REMOVEFILTERS関数の引数にテーブルを指定してあげればいいってこと?という解釈はしないほうがよくて、現在の検証は列もすくなく、行も少ない、シングルテーブルで行っています。実際には複数テーブルがあり、リレーションシップで構成されたデータモデルがあるはずです。その場合はさきほどのクラスター作成がより複雑になり、より直感的ではなくなります。

ということで…

SUMMARIZE関数のベストプラクティス

列のグループ化にだけ使うこと!

集計列をSUMMARIZE関数で追加しようとすると、前述したクラスターが作成されてからの動きをよーく考える必要がでてきて、直感的ではない記述をする必要があります。ですので、SUMMARIZE関数は列のグループ化のみに使用しましょう。

じゃあ集計列の追加はどうすればいいの…?🤔

ADDCOLOMNS関数研究記事に続く👍

参考資料

23
6
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
23
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?