当日フィルターを設定した状態で前日比を表示したい

periodOverPeriodDifference関数を使って前日比を計算しています。
最新日付フィルターした状態だと、値が表示されません。
(相対日付フィルターではなく、日付項目に格納されているうちの最新日付にフラグをつける形で実現)

前日分を含めると表示されることは理解していますが、
他の表示項目との兼ね合いで、前日分は表示させたくありませんが、なにかうまいやり方はないでしょうか。

ピボット形式で periodOverPeriodLastValue を利用した時のフィルターについて - 日本語で質問 | Q&A - Amazon Quick Community
こちらに記載されているDataHiderの項目をフィルターに設定した際に1日に絞った場合も値が表示されるようになりましたが
常に日付項目内の最新日付でフィルターをしたいのですがうまくいきません。
フィルタータイプが「日付の範囲」「相対日付」「上位と下位」の3種類あります。
「上位と下位」フィルターで 上位1日を指定するとビジュアル上「クエリを解析できません」といったエラーになります

@kiriyama
ご質問いただきありがとうございます。

以下、回答になります。


原因

periodOverPeriodDifference / periodOverPeriodLastValue はテーブル計算(Table Calculation)です。Amazon QuickSight の評価順序において、通常のフィルターは「PRE_AGG」レベル(ステップ2)で適用されますが、テーブル計算は「ビジュアルレベル」(ステップ4-2)で評価されます。

そのため、日付フィルターで最新1日のみに絞ると、テーブル計算が実行される時点では前日データが既にクエリ結果から除外されており、比較対象がないため値が空になります。

「上位と下位」フィルターでエラーになる理由

「上位と下位」フィルターは評価順序ステップ 2-3(PRE_AGGレベル)で適用されます。日付フィールドに対して「上位1日」を指定した場合、集計前に最新1日のみにデータが絞られるため、テーブル計算(periodOverPeriod)の実行時には前日データが存在せず計算不能となります。加えて、日付型フィールドに対する上位と下位フィルターは想定外の組み合わせとなり、「クエリを解析できません」エラーが発生します。


回避策

方法1(推奨): テーブル計算を利用した DataHider

考え方: 通常の日付フィルターを使わず、テーブル計算レベルで表示/非表示を制御します。テーブル計算のフィルターは評価順序の最後(ステップ4-2の後)で適用されるため、periodOverPeriod 計算が完了した後に不要な行を非表示にできます。

参照:

手順:

① 計算フィールドを作成(分析レベル)

MaxDate = maxOver(max({日付}), [])

maxOver の第3引数(計算レベル)を省略すると、デフォルトの POST_AGG_FILTER(テーブル計算レベル)で評価されます。これにより periodOverPeriod 計算と同じステップで最新日付が算出されます。

注意: PRE_FILTERPRE_AGG レベルを指定した場合、第1引数に集計関数(max() 等)は使用できません(公式ドキュメント参照)。ここではデフォルトの POST_AGG_FILTER を使用するため、max({日付}) を第1引数に指定しています。

② DataHider 計算フィールドを作成(分析レベル、テーブル計算)

DataHider = ifelse(max({日付}) = {MaxDate}, "Show", "Hide")

{MaxDate} はテーブル計算の結果を参照しているため、DataHider もテーブル計算として扱われます。ifelse の条件内で max({日付}) を使うことで、ビジュアルレベルの集計日付と比較します。

③ ビジュアルに DataHider をフィルターとして追加

  • ビジュアルのフィルターペインで「DataHider」を追加
  • DataHider はテーブル計算を参照しているため、テーブル計算フィルターとして自動的にステップ4-2の後に適用されます
  • 「Show」のみを含める設定にする

④ 日付フィールドはビジュアルのフィールドウェルにそのまま配置(フィルターなし)

ポイント: DataHider がテーブル計算レベル(POST_AGG_FILTER)で動作する理由は、maxOver をデフォルトの計算レベルで使用しているためです。PRE_FILTER を指定してしまうと、フィルターが periodOverPeriod 計算より前に適用されるため、目的を果たせません。

補足 — Community 記事との実装差分について: 参照元の Qiita 記事および Community 記事では、以下の計算式が紹介されています。

minOver(min({日付}), [{日付}])

これは「各日付行ごとにパーティションした最小値」を返すため、結果的に各行の日付がそのまま返る形式です。このフィールドを日付フィルターの対象として使うことで、元の日付フィールド自体にフィルターを掛けることを回避し、テーブル計算を壊さないようにする手法です。 本回答では maxOver(max({日付}), []) + ifelse による “Show”/“Hide” 方式を採用しています。これは以下の理由によります。

  • 質問者の要件「常にデータ内の最新日付に自動で絞りたい」に対応するため: minOver 方式は相対日付フィルターとの組み合わせを前提としており、「データ上の最新1日のみを動的に特定して表示」するには追加のロジックが必要です。maxOver でデータ全体の最大日付を算出し、それと一致する行のみ表示する方が、最新日付への自動追従がシンプルに実現できます。
  • パーティション指定の違い: minOver(min({日付}), [{日付}]){日付} でパーティションしているため行ごとの自身の値が返りますが、maxOver(max({日付}), []) はパーティションなし(全行横断)で最大日付を返します。目的が異なるため、計算式も異なります。
  • いずれの方式も原理は同じ: テーブル計算レベル(POST_AGG_FILTER)で動作するフィールドを作り、そのフィールドでフィルターすることで、periodOverPeriod 計算の後にフィルタリングが行われるようにする点は共通です。

方法2: lag による前日比計算(periodOverPeriod関数を使わない)

periodOverPeriod 関数を使わず、lag で前日値を取得して差分を計算する方法です。

参照:

① 前日値(テーブル計算)

PreviousValue = lag(sum({売上}), [{日付} ASC], 1)

lag はテーブル計算関数です。ソート順に [{日付} ASC] を指定し、1行前の値(= 前日の売上合計)を取得します。

② 前日比(テーブル計算)

DoD_Diff = sum({売上}) - {PreviousValue}

③ DataHider でフィルター

方法1と同様に maxOver で最新日付を判定し、テーブル計算フィルターで最新行のみ表示します。


方法3: パラメータ + 計算フィールドで日付範囲を制御

フィルターではなくパラメータで日付範囲を制御する方法です。データには前日+当日の2日分を含め、表示のみ当日に絞ります。

参照:

① パラメータ作成

pLatestDate(日時型)を作成します。

② 日付範囲制限用の計算フィールド(分析レベル)

DateRangeFilter = ifelse(
  {日付} >= addDateTime(-1, 'DD', ${pLatestDate}) AND {日付} <= ${pLatestDate},
  "Include", "Exclude"
)

addDateTime の第2引数 'DD' は「日」を表します(公式ドキュメント参照)。パラメータ ${pLatestDate} の1日前から当日までを “Include” とします。

③ 通常のフィルターとして適用

DateRangeFilter = "Include" を通常フィルターとして適用します(前日 + 当日の2日分を含める)。

④ 表示用の DataHider(テーブル計算フィルター)として当日行のみ表示

方法1と同様の DataHider テクニックで、ビジュアル上には最新日付の行のみ表示します。

注意: パラメータのデフォルト値を「常にデータ内の最新日付」に動的に設定する標準機能はありません。コントロール(日付ピッカー)で手動設定するか、相対日付フィルターとの併用を検討する必要があります。


まとめ

方法 メリット デメリット
方法1: DataHider + maxOver periodOverPeriod関数をそのまま活用可、最新日付が自動追従 テーブル計算フィルターの仕組みの理解が必要
方法2: lag で前日比計算 フィルター制約に縛られにくい 計算フィールドを複数作成する手間
方法3: パラメータ制御 柔軟性が高い パラメータを「常に最新日」にする自動化が難しい

推奨は方法1です。ポイントは「日付の範囲」「相対日付」「上位と下位」といった通常の日付フィルターは使わずmaxOver + ifelse で作成した DataHider をテーブル計算フィルターとして適用することです。


参考情報

ありがとうございます。方法1で解決できました。