2025/12/18

テクノロジー

Tableau IF文ミステリィ - すべてがIFになる

この記事の目次

    本記事は【Advent Calendar 2025】の14日目の記事です。


    デジタルプラットフォーム統括本部データソリューション統括部データアーキテクト部アナリティクス推進課のA・Kです。

    そういえば自分でも久しく忘れていたのですが、ミステリーや推理小説、叙述トリック物の小説が好きで昔よく読んでいました。タイトルで分かった方もいるかもしれませんが、好きな作家は工学博士の森博嗣先生です。
    ということで、今回はBIツールTableauのIF文にまつわるミステリーを書こうと思います。

    0. プロローグ

    Tableauには「計算フィールド」という概念があります。計算フィールドを使うと、定数・変数を交えた算術計算や文字列操作などの結果をフィールドに出力することができ、主に動的な出力を得たい場合に利用します。
    例えば、顧客への商品販売履歴が記録されている以下のようなテーブルがあるとします。

    注文ID注文日ユーザーIDユーザー名都道府県定価購入額
    2025-6456142025/1/30U-562596鈴木 花子富山県4000040000
    2025-7481092025/3/29U-585788吉田 直樹新潟県180000180000
    2025-3883602025/4/18U-577077高橋 健佐賀県260000208000
    2025-3551112025/5/3U-750671斎藤 真紀青森県250000250000
    2025-4205882025/5/4U-362222中村 真由宮城県200000200000
    2025-2906292025/5/16U-013025佐藤 太郎沖縄県130000104000
    2025-2770392025/6/22U-715673渡辺 彩茨城県20000040000
    2025-8640822025/7/28U-577077高橋 健佐賀県300000300000
    2025-9739222025/9/30U-909473小林 誠東京都180000180000
    2025-0913622025/11/22U-446022加藤 結衣栃木県3000024000

    このテーブルをTableauで読み込み、「どのくらいの割引率で購入してもらったのか」の列を追加して可視化する場合、以下の計算フィールドを作成し新たな列として追加することで実現できます。

    割引率
    ([定価] - [購入額]) / [定価]

    1. 双頭の悪魔

    まず、以下の記述をご覧ください。

    IF SIZE() = 1 THEN (SUM([定価] - [購入額])) / SUM([定価])
    ELSE (SUM([定価] - [購入額])) / SUM([定価])
    END
    

    Tableauの計算フィールドにおけるIF文のフォーマット(今回のケースに相当するもの)は、以下のとおりです。

    IF <条件> THEN <条件に合致する場合の出力>
    ELSE <条件に合致しない場合の出力>
    END
    

    また、SUM関数は指定したカラムの値をさまざまな粒度(全体、一部のグループにおいて、など)で合計することができます。

    つまり、はじめに掲載した記述は、条件「SIZE() = 1」に合致する場合 (SUM([定価] - [購入額])) / SUM([定価]) (=複数レコードの割引率) を返し、条件に合致しない場合 (SUM([定価] - [購入額])) / SUM([定価]) を返します。
    …って、え?これどっちの計算式も同じくない?????
    はい、そうです。この条件に合致する場合としない場合の計算式は、まったく同じ計算式です。

    「分かった!これ本当はIF文を使わなくても実現できるけど、無理やりIF文にしてるだけだろ!」と予想した方がいるかもしれませんが、残念ながら今回のケースではIFを使い条件分岐させないと正しい結果を得られません

    5. ここでいきなりエピローグ

    …こうして作成した計算フィールドを使い、以下のような集計結果の表示を実現することができました。めでたしめでたし。

    総計という行が追加されていることが分かると思います。総計はTableauがデフォルトで持つ集計機能で、各レコードをさまざまな粒度で合計したり平均したりすることができます。
    今回は定価や購入額の平均単価、平均割引率を表示したかったので、「平均により集計を行った総計」を最終行に表示することにしています。

    2. 真夏の総計式

    さて、総計はTableauのデフォルトの機能とお伝えしましたが、実はトラップがあります。以下の表は、平均による総計機能を単純に適用したときの集計結果です。

    一見どこがおかしいのか分かりにくいですが、前項で掲載したキャプチャとの違いは割引率の総計です。前項キャプチャでは13.8%だったのに対し、今回は14.0%となっています。これはどちらが正しいのでしょうか?

    ということで正しい計算をしてみます。割引率の平均とは、いわば全体に均した(ならした)ときの割引率にあたるので

    割引金額の合計 ÷ 定価の合計

    で算出することができます。実際に計算してみます。

    割引金額の合計 = 244,000
    定価の合計 = 1,770,000
    割引金額の合計 ÷ 定価の合計 = 0.1378 ≒ 13.8%

    ということで、正しい値は13.8%でした。え…?では、14.0%というのはどこから来た数値なのでしょうか?

    実は、総計機能の平均は以下赤枠部分の平均を集計しています。

    (0 + 0 + 20 + … + 20)÷ 10 =14.0 ですね。このように、総計機能は各レコードの値を単純に算術計算して集計を行うのですが、割合の平均は算術平均で求めることができません。これが総計のトラップです。

    では、定価と購入額の集計には算術平均を使い、割合の平均を集計するときは別の計算を行うにはどうすればいいのでしょうか?

    3. GYOTH

    あらためて、冒頭に出てきた計算式を再度見てみます。

    IF SIZE() = 1 THEN (SUM([定価] - [購入額])) / SUM([定価])
    ELSE (SUM([定価] - [購入額])) / SUM([定価])
    END
    

    ここで気になるのが SIZE() = 1 という条件です。SIZE() とはどのような関数なのでしょうか?
    結論、 SIZE関数は各レコードが属するパーティション内の行数を返します。パーティションという単位がどこを表すかというと、以下の図のとおりです。

    従って、各行に SIZE関数を適用すると、以下の値が返ってきます。

    犯人が見えてきましたね。

    4. イニシエーション・サム

    従って、

    割引率
    
    IF SIZE() = 1 THEN (SUM([定価] - [購入額])) / SUM([定価])
    ELSE (SUM([定価] - [購入額])) / SUM([定価])
    END
    

    この計算フィールドを作成することにより、SIZE() = 1 、つまり総計の行において各レコードの平均を計算せず (SUM([定価] - [購入額])) / SUM([定価]) を計算し、また SIZE() ≠ 1 、つまり総計以外のすべての行においても (SUM([定価] - [購入額])) / SUM([定価]) を計算することができるようになります。

    ここで1つ、最後の疑問が残ります。「総計以外の行はすべて1行ごとに割引率を計算するんだから、わざわざSUMを使って合計する必要はないのでは?」

    その答えは2つあります。1つは、そういう仕様だからです(SUMなど集計関数をつけないとエラーが出ます)。なんだそりゃ、と思う方もいるかもしれませんが、これは合理的な仕様です。その合理性が分かるもう1つの理由が、Tableauはデータ分析に使うツールなので、以下のように別の切り口でも分析してみたいというニーズがありえる点です。この場合、地域ごとに定価の合計、割引額の合計を算出するためにSUMを行う必要があるのは明白です。

    5. エピローグ

    …こうして作成した計算フィールドを使い、以下のような集計結果の表示を実現することができました。めでたしめでたし。

    6. あとがき

    ということで、Tableau IF文ミステリィでした。今回のケースは、実際に業務でのレポート作成中に直面した問題がベースになっています。私自身、IF文の条件に合う場合と合わない場合でまったく同じ計算式を使う、という経験がこれまでなかったので、このような方法で解決できたことが非常に興味深かったです。

    Tableauはこのような形で計算フィールドを活用し、集計を行うことができます。このミステリーもどきでTableauに興味を持たれた方は、さまざまな機能や計算フィールドを使ってデータの可視化にチャレンジしてみてください!新たな発見があるかもしれません。

    以上、ヴァン・ダインでした。

    イベント告知

    12月23日にイベントを開催します!申し込みはこちらから▼

    https://mynaviit.connpass.com/event/376769

    ※本記事は2025年12月時点の情報です。

    著者:マイナビエンジニアブログ編集部