【正解】C
【0からの解説】
①前提知識:
・UNION(UNION ALL / UNION DISTINCT)は、同じ列構成の複数のテーブルの行を縦に積み重ねて 1 つの結果にまとめる演算です。地域ごとに分かれた同じ構造の売上テーブルを 1 つにまとめるのに適しています。一方 CROSS JOIN はテーブル同士のすべての行の組み合わせ(直積)を作る演算で、行数が掛け算で増え、売上の集計には使えません。
・マテリアライズド ビュー(実体化ビュー)は、クエリ結果を事前に計算して保存し、ベーステーブルが変更されると BigQuery が自動的に再計算(リフレッシュ)するビューです。通常のテーブルは作成時点のスナップショットにすぎず、元テーブルが更新されても自動では変わりません。UNION を含む定義は「非増分マテリアライズド ビュー」(allow_non_incremental_definition オプションと max_staleness オプションを指定)として作成できます。
・RANK() と ROW_NUMBER() はどちらもウィンドウ関数(分析関数)です。ROW_NUMBER() は同順位があっても必ず 1, 2, 3… と一意の番号を振るため、売上が同額の地域があると任意にどちらかが落ちます。RANK() は同じ値に同じ順位を付ける(1, 2, 2, 4…)ため、同額の地域を公平に扱えます。
②要件と制約語の整理:(a) 地域ごとに個別のテーブル(毎月更新)、(b) 月ごとの売上上位 3 地域を特定、(c) 今後 3 か月間、「最新の結果を自動的に提供」する。
③正解の理由:UNION で全地域のテーブルを 1 つにまとめたマテリアライズド ビューを作れば、毎月元テーブルが更新されるたびに結果が自動的にリフレッシュされます。そのビューに対して月ごとに PARTITION BY した RANK() で順位を付け、上位 3 を抽出すれば、同額の地域も正しく扱いながら常に最新のランキングを得られます。
【誤りの選択肢】
A:UNION による統合は正しいものの、通常の「テーブル」として作成すると作成時点のデータで固定され、元の地域別テーブルが毎月更新されても反映されません。「最新の結果を自動的に提供」という要件を満たさず、毎月作り直す手作業が必要になります。また ROW_NUMBER() は同順位を区別して一意に番号を振るため、売上が同額の地域があると上位 3 の判定が不公平になります。
B:CROSS JOIN は全行の組み合わせ(直積)を作るため、地域ごとの売上を 1 列にまとめることができず、行数が爆発的に増えて正しい集計になりません。さらに通常のテーブルなので自動更新もされません。
D:マテリアライズド ビューで自動更新はできますが、CROSS JOIN では地域別テーブルを正しく統合できず、売上ランキングの元データとして成立しません。ROW_NUMBER() も同順位を扱えない点で RANK() に劣ります。
【参考】
マテリアライズド ビューを作成するマテリアライズド(実体化)ビューの概要