こんにちは。エクスチュアの大吉です。
前回の記事では、LOD(Level of Detail)の考え方や、
「ビューの粒度」と「計算の粒度」がズレたときにLODが必要になる、という話をしました。
今回はLODの中でも、
特につまずきやすく、かつ実務でよく使う「FIXED」 にフォーカスして解説していきます。
- フィルターをかけても数値が変わらない
- なぜか全行同じ値になる
- 正しく動いているはずなのに、不安になる
そんな経験がある方は、ぜひ最後まで読んでみてください。
目次
- FIXEDでよく見る「違和感」
- FIXEDとは何か
- サンプルスーパーストアで見る「普通の集計」
- FIXEDが必要になるとき
- FIXEDを使ってみる
- なぜフィルターをかけても値が変わらないのか
- コンテキストフィルターを使うとどうなるか
- FIXEDを使うときの思考フレーム
- まとめ
FIXEDでよく見る「違和感」
まずは、FIXEDを使ったときによく見る画面からです。

行
オーダー日(日)とカテゴリ
マーク > テキスト
カテゴリ別売上
{ FIXED [カテゴリ] : SUM([売上]) }
マーク>色
カテゴリ
日付は違うのに、同じカテゴリであれば数値がすべて同じになっています。
「FIXEDって、ちゃんと効いてるの?」
「なんかおかしくない?」
そう思ったことがある方も多いのではないでしょうか。
ですが、これは FIXEDが正しく動いている状態 です。
FIXEDとは何か
FIXEDを一言で表すなら、こうなります。
「ビューに関係なく、この粒度で先に計算する」
ここで重要なのは、「ビューに関係なく」 と 「先に」 という2点です。
FIXEDは、「今どんなビューを作っているか」よりも前に、指定した粒度で一度計算結果を確定させる仕組みです。
言い換えると、
FIXEDは 元のデータソースを直接集計しているのではなく、指定した粒度で集計した「中間テーブル」を先に作成していると考えることができます。
この性質が、先ほどの「違和感」の正体でもあります。
サンプルスーパーストアで見る「普通の集計」
まずはLODを使わない、通常の集計を確認してみます。

行
オーダー日(日)とカテゴリ
マーク > テキスト
SUM(売上)
マーク>色
カテゴリ
この場合、オーダー日毎のカテゴリ別の売上合計が表示されます。
これはとても自然な動きです。
粒度が「日付」×「カテゴリ」なので、売上も「日付」×「カテゴリ」単位で集計されています。
Tableauでは、
ビューに置いたディメンションが、集計の粒度を決めている
ということが、よく分かる例です。
この通常の集計では、データソースをそのまま使って集計が行われています。
FIXEDが必要になるとき
では、次のような要件を考えてみます。
日別の売上を見ながら、各カテゴリの「月次売上目標」も一緒に表示したい
ここで重要なのは、
目標値は「カテゴリ×月次」単位で決まっているという点です。
このとき、
- ビューの粒度:オーダー日(yyyy-mm-dd)×カテゴリ
- 本来固定したい粒度:オーダー日(yyyy-mm)×カテゴリ
というズレが発生します。
LODを使用せず、目標売上をビューに入れると以下のような挙動をします。

行
オーダー日(日)とカテゴリ
マーク > テキスト
SUM(売上)
SUM(目標売上)
本来は固定されるべき目標値が、日付単位で分割されてしまいました。
ここで初めて、粒度を明示的に固定する必要が出てきます。
FIXEDを使ってみる
そこで、次のLOD計算を作成します。
{ FIXED DATETRUNC('month',[オーダー日]),[カテゴリ] : SUM([目標売上]) }
この式が言っていることは、とてもシンプルです。
「年月とカテゴリ単位で、目標売上を合計して」
ですが、内部的には
「年月とカテゴリ単位で集計した中間テーブルを1つ作成している」
と考えると、より理解しやすくなります。
この計算フィールドを、先ほどの日別ビューに配置してみます。

行
オーダー日(日)とカテゴリ
マーク > テキスト
SUM(売上)
SUM(カテゴリ_月別目標売上)
すると、日付が変わっても、カテゴリごとの目標売上は変わりません。
これは、FIXEDが
ビューとは切り離された粒度で中間テーブルを作成し、その結果をビューに貼り付けている
からです。
なぜフィルターをかけても値が変わらないのか
ここで、さらによくある疑問が出てきます。
「地域でフィルターをかけたのに、値が変わらない」

フィルター
地域を関東地方、関西地方、九州に限定する。
先ほどのビューと比較すると売上 は変わるのに、目標売上は変わらないです。
これも、FIXEDでよくつまずくポイントです。
FIXEDは、
中間テーブルを作成する処理が、多くの通常フィルターよりも先に行われます。
※Tableauに複数存在するフィルターの順番によるものですが、今回は詳細は省きます
そのため、「フィルターをかけたのに FIXED の計算結果は変わらない」という現象が起きます。
これはバグではなく、Tableauの計算順序(クエリパイプライン)によるものです。
コンテキストフィルターを使うとどうなるか
同じフィルターでも、コンテキストフィルターにすると挙動が変わります。

操作
地域フィルターを「コンテキストに追加」します。
コンテキストフィルターは、FIXEDで中間テーブルを作成するよりも前に評価されます。
そのため、中間テーブルの作成対象そのものが変わり、FIXEDの計算結果にも影響が出るようになります。
ここで重要なのは、
「コンテキストを使いこなすこと」ではありません。
FIXEDは、粒度の話であり、同時に「中間テーブルを作る順番」の話でもある
という点を理解することです。
FIXEDを使うときの思考フレーム
最後に、FIXEDを書く前に考えてほしいことをまとめます。
- 今のビューの粒度は何か
- 本当に固定したい粒度は何か
- その固定値は、どのデータを使って集計する(中間テーブルを作る)べきか
- フィルターの影響を受けたいか、受けたくないか
FIXEDは強力な反面、中間テーブルを意識せずに使うと混乱を招きやすいLODでもあります。
この視点を持つだけで、「なんとなくFIXEDを書く」ことは減っていくと思います。
まとめ
いかがだったでしょうか。
FIXEDは、「ビューに関係なく、この粒度で先に計算する」という特性を持っています。
その正体は、指定した粒度で集計した中間テーブルを作成することです。
FIXEDを使っていると
- 数値が変わらない
- フィルターが効いていないように見える
といった違和感が生まれます。
ですが、「FIXED=中間テーブルを作成している」と理解できれば、その挙動はとても自然なものに見えてきます。
FIXEDは、「目標値」などの「固定されるべき指標」を扱う上で、とても心強い武器になります。
次回以降、INCLUDE/EXCLUDE といったLOD関数について解説していく予定です。
ぜひ、そちらもあわせて読んでみてください。











