要するに、処理が .sql と .yml の2箇所に散るのが問題。重複排除のような前処理は、そのモデルのSQLファイルの中に置いた方が読める。
なお source(sources.yml)にはそもそも pre-hook を定義できない。
重複排除は QUALIFY句と ROW_NUMBER() を使うのがいちばん短い(BigQueryの場合)。処理を切り離したいときは方法3の中間モデルにする。
方法1: QUALIFY句とROW_NUMBER()を使用(推奨)
-- sample_model.sql
SELECT *
FROM {{ source('raw_data', 'raw_data') }}
QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY _load_ts DESC) = 1
方法2: CTEとウィンドウ関数を使用
WITH ranked_data AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY _load_ts DESC) AS rn
FROM {{ source('raw_data', 'raw_data') }}
)
SELECT *
FROM ranked_data
WHERE rn = 1
方法3: 中間モデルを作成して処理を分離
-- staging/raw_data_deduplicated.sql
SELECT *
FROM {{ source('raw_data', 'raw_data') }}
QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY _load_ts DESC) = 1
-- staging/sample_model.sql
SELECT *
FROM {{ ref('raw_data_deduplicated') }}
WHERE condition = 1
基本的には避けるべきだが、やむを得ない場合のみ。必ずコメントで理由を明記する・ドキュメントに記録する・チームメンバーと相談する。
ROW_NUMBER() の側