今回の課題
BigQueryのデータ基盤の差分更新を添付の記事のように実装していたのだが、
MERGEステートメントを使用することでも実装できそうだったので、試してみようと思った。
MERGEステートメント
INSERT, UPDATE, DELETEオペレーションを1つのステートメントに結合し、オペレーションをアトミックに実行できるDMLステートメントです。
※引用:MERGEステートメント(BigQuery公式ドキュメント)
前日分のデータを差分更新したい場合のクエリ
コメントアウトで、部分毎にどういった処理をしているか記入致しました。
/* 日付関連UDF */
create temp function yesterday() as (
date(date_sub(current_date(), interval 1 day))
);
/* 差分更新をするクエリ */
merge
`変更するテーブル名` as a -- 差分追加先のテーブル
using -- ソーステーブルからデータを抽出する
(
with master as (
select
date(date) as date -- date型に変換
, page_title
, user_type
, page_path
, regexp_replace(normalize(page_path, NFKC), r'(index|&|\?|https).*|[^a-zA-Z0-9 -/:-@-~_]|[ +:\?#]', '') as page_path_fix --データの揺れを調整
, pageviews -- pv数
, users -- uu数
from
`ソーステーブル名`
where
date = yesterday() -- 1日前を差分更新したいので、一日前にフィルタリング
)
select
date
, page_title
, user_type
, page_path
, page_path_fix
, pageviews
, users
from
master
) as b
on -- どのカラムをキーにして、データの有無を判断するか指定
a.date = b.date
and a.page_title = b.page_title
and a.user_type = b.user_type
and page_path = b.page_path
when matched then -- onの部分でキーに指定したデータが存在する場合に更新する数値のカラムを指定
update set
a.pageviews = b.pageviews
, a.users = b.users
when not matched then -- onの部分でキーに指定したデータが存在しない場合に挿入する数値のカラムを指定
insert(
date
, page_title
, user_type
, page_path
, page_path_fix
, pageviews
, users
)
values( -- 挿入する数値を指定
b.date
, b.page_title
, b.user_type
, b.page_path
, b.page_path_fix
, b.pageviews
, b.users
);