BigQuery で月別にテーブルを分けていた時に、クエリを動的に生成せず「今月」や「直近10日分」を対象とした検索したかったので。
Table wildcard function を利用すると、クエリの FROM の対象テーブルを柔軟に設定出来そうです。Table wildcard function は以下の 3 つの関数があるのですが、
- TABLE_DATE_RANGE
- TABLE_DATE_RANGE_STRICT
- TABLE_QUERY
TABLE_DATE_RANGE
と TABLE_DATE_RANGE_STRICT
はテーブル名に YYYYMMDD 形式で日付を含む日別テーブルしか扱えないようなので、今回は TABLE_QUERY
を利用します。
テーブル名が以下のルールだった場合、
- apache.access201401
- apache.access201402
- apache.access201403
- apache.access201404
- ...
「今月」のテーブルを指定するには、FROM 句に次のように記述します。TABLE_QUERY
の2番目の引数に条件式を指定するのですが、そこでは table_id
がテーブル名を示します。
SELECT .....
FROM TABLE_QUERY(apache, "table_id=STRFTIME_UTC_USEC(now(), 'access%Y%m')")
WHERE .....
「直近10日」のデータを含むテーブルは、現在時刻によって今月のテーブルだけにおさまるケースと先月のテーブルにまたがるケースがあるので、少し複雑になります。now()
はマイクロ秒単位の時刻を返すので、10日前を指定するためにそこから 10 * 86400000000(1日のマイクロ秒数)を引いています。
SELECT .....
FROM TABLE_QUERY(apache, "table_id=STRFTIME_UTC_USEC(now(), 'access%Y%m') or table_id=STRFTIME_UTC_USEC(now()-10*86400000000, 'access%Y%m') ")
WHERE .....
こうすることで、10日前が今月であれば今月のテーブルのみが対象となり、10日前が先月であれば先月と今月のテーブルが FROM の対象となります(実際には WHERE 句で直近10日分を指定する条件も必要ですが、ここでは FROM 句の指定のみに着目しています)。BigQuery はスキャンするデータ量に応じて料金がかかるので、必要なテーブルのみをスキャンすることでコストを節約することができます。