はじめに
カユいところに手を届かせるためのスーパー機能、計算フィールド。
ちゃちゃっと使いこなせればかっこいい! とは思いつつ、ちょっとでも込み入ったことをしようとすると、すぐに怒られてしまうのでついつい敬遠してしまいます。
なので、今回は計算フィールドさんに
集計および非集計の引数を混在させることはできません
と怒られないために、この辺りのルールを整理したいと思います。
(こんな式を書けば、手っ取り早くこのこの怒られ方をします)
これは、非集計と集計の違いを理解すれば、怒られるのを回避できます。
非集計と集計
非集計はレコード1つ1つそのもので、複数の値をまとめたりしてないものを指します。
なので、[売上]
のように書いた非集計の値は、全レコードに存在する売上の値全てを指します
売買履歴レコードが10個あったら、それぞれ10個の売上の値すべてをまとめて指してるわけです。
一方で、集計は文字通り、複数のレコードの値をなんらかの方法で1つにまとめることを指します。
10個の売買履歴レコードがあったときに、その売上の合計として1つの値を出す、とかですね。
SUM()とかAVG()とかMAX()とかが集計関数に当たります。
なので、SUM([売上])
のような集計の値は、集計結果のたった1つの値を指します
で、なにがTableauを怒らせるのか
集計と非集計の計算を混在させて怒られる理由として、しばしば
「1つ1つの売上(非集計)と、全体の売上合計(集計)を足す、という計算が意味を成さないから」
という説明を見かけますが、これが個人的には混乱を招きました。
例えば、1つ1つの売上が全体の平均からどれくらい高いか、とかの計算はしたくなるなじゃん、と思うわけです。
実際、そういう計算をしようとしてるから計算フィールドに書いて怒られてるわけですから。
では、自分的に納得のいく怒られる理由は何かというと、
集計と非集計とで、Tableauがやる計算のモードが違うから
…なんかもやっとした言い方になってしまいましたので、もっとちゃんと説明します。
非集計と非集計の計算
前述の通り、非集計はレコードに書いてある値そのものです。
なので、非集計と非集計の計算というのは、1つ1つのレコードに対して個別にやるわけです。
例えば10個の売買履歴レコードがあったとして、利益を求めるために
[売上] - [原価]
とすると、これは10個のレコード1つ1つにこの計算を適用することになります。
なので、非集計と非集計の計算は、レコードの個数だけ計算を繰り返するイメージになります
集計と集計の計算
次に、集計は複数のレコードの値を1つにまとめた値です。
SUM([売上]) - SUM([原価])
とすると、まずSUM([売上])最初に10個のレコードの売上を合算して、原価を合算して、最後にその合算した数値を引き算します。
なので、集計と集計の計算は、すでに全レコード分の値が1つにまとまっている数値について、1回だけ計算するイメージです。
Tableauさんが起こる理由
つまり、集計と非集計の混在した式を書かれると、Tableauさん的には1行1行計算して欲しいのか、まとめて1個だけ計算して欲しいのかの区別がつかないわけです。
ずいぶん長い解説になってしまいましたが、どちらのモードで計算するのかわからなくて、怒ってくるわけです。
でも、混在させたいんだ! というときに
とはいえ、前述の通り「1つ1つの売上(非集計)が全体の平均(集計)からどれくらい高いか」
のように、集計と非集計とを混在させたいタイミングがあるわけです。
集計→非集計に変換する
「1つ1つの売上(非集計)が全体の平均(集計)からどれくらい高いか」` というケースのように、集計を非集計に変換したいときに使うのがLOD表現です。
(以前書いたまとめ↓)
LOD表現は、異なるLOD(詳細レベル)の計算を混在させるための関数ですが、今回のケースでいうと、集計を非集計にする効果があります。
FIXEDやEXCLUDを使って上位のLODで表現を使うと、最小のLODであるレコード単位の計算に、上位のLODである全体の集計を持ってこれる、というわけです。
集計した1つの値を各レコードにコピーして配布する、というイメージなのですが、伝わりますでしょうかね?
なので、↓のようにすれば「1つ1つの売上(非集計)が全体の平均(集計)からどれくらい高いか」
が集計と非集計を混在させることなく実現できるわけです
非集計 → 集計に変換する
一方で、非集計を集計に変換したいケースもまれにありますが、これは集計しちゃえばいいわけですから簡単です。
SUM()とかを使っちゃうと値が変わってしまうので、非集計の時の値をそのまま使うには、MAX()とかを使うことが多いですね。
まとめ
計算フィールドで出てくるエラーって、基本的にそれ以上の情報がないので、遭遇すると思わず「ぐぬぬっ」と身構えてしまいます。
が、Tableauさんも意地悪を言っているわけではないので、1つ1つの仕様をちゃんと理解することで回避することができます。
他にも怒られるケースがあるので、そのうちまたまとめたいと思います、