
このSQLで解決できる課題
LPや商品詳細、料金ページの改善では、ユーザーが“次に”どこへ進んだかを把握するのが近道です。
GA4の標準レポートでもナビゲーション概要は見られますが、自社のKPIに合わせた粒度(特定ページのみ・重複除外・URL正規化・セッション母数に対する遷移率など)まで落とし込むのは難しく、改善会議で「どの導線を強化/削除するか」を即断できないことが多いはず。
本SQLは、GA4の events_*
から page_view だけを抽出し、同一ユーザー×セッション内の時系列で LEAD()
を使って**“次ページ”を決定。
対象の起点ページ(YOUR_TRIGGER_PAGE
)を訪れた全セッションの母数と、そこから実際に別ページへ遷移したセッション数を遷移先ごと**に集計します。
出力は、起点パス / 遷移先パス / 遷移セッション数 / 起点母数 / 遷移率。
これにより「LPからそのままカートに行った割合」「FAQへ逸れてしまう割合」「別商品の詳細に流れてしまう割合」を数字で比較でき、CTA配置の見直し、FAQ要点のLP内包、無駄な外部リンク削減など、施策に直結する意思決定が可能になります。
実行結果イメージ
-
背景・利用シーン
LP改善の優先順位付け:カート・フォームへの直行が低いなら、ファーストビューやCTA配置の見直し。
FAQ/ヘルプ流入の最適化:FAQ遷移が多いなら、LP側に要点を前倒しして**“行かなくても済むFAQ”**へ。
商品回遊の導線設計:似た商品へ流れるなら、比較表やおすすめの並びを改善。
広告整合性の検証:意図した次ステップに進んでいるか、キーワード/クリエイティブの整合性を確認。
抽出結果からできる議論(会話例)
マーケ担当A: 「LPからカートに直行するのは24%しかないですね。」
分析担当B: 「FAQに10%流れているのが気になります。LPに情報を追記するべきかも。」
マーケ担当A: 「この商品ページに誘導したいのに、別商品の詳細に流れてますね。」
分析担当B: 「一覧ページでの見せ方を変える必要がありそうです。」
分析担当B: 「コンタクトフォームに進む割合が6%しかないですね。」
マーケ担当A: 「ボタン配置を見直したほうが良さそうです。」
マーケ担当A: 「広告経由のユーザーは、意外と商品詳細よりFAQに行ってますね。」
分析担当B: 「LPの説得力が弱い証拠です。改善ポイントが見えてきました。」
マーケ担当A: 「遷移率が高い導線は、そのまま強化したいですね。」
分析担当B: 「逆に低い導線は、思い切って削除するのもアリです。」
SQLコードと解説
-- ① イベントデータを取得
WITH base_events AS (
SELECT
user_pseudo_id,
(SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS ga_session_id,
event_timestamp,
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') AS page_location
FROM
`YOUR_PROJECT_ID.YOUR_DATASET_ID.events_*` -- ★ プロジェクト・データセットを指定
WHERE
event_name = 'page_view' -- ページ閲覧イベントのみ抽出
),
-- ② ページ遷移を取得(次ページを特定)
page_views AS (
SELECT
user_pseudo_id,
ga_session_id,
event_timestamp,
page_location,
LEAD(page_location) OVER (
PARTITION BY user_pseudo_id, ga_session_id ORDER BY event_timestamp
) AS next_page
FROM base_events
),
-- ③ 起点ページを訪れた全セッションを取得(母数)
trigger_sessions AS (
SELECT DISTINCT
REGEXP_REPLACE(page_location, r'^https?://[^/]+', '') AS trigger_page_path,
user_pseudo_id,
ga_session_id
FROM page_views
WHERE page_location LIKE '%YOUR_TRIGGER_PAGE%' -- ★ 対象ページを指定
),
-- ④ 有効な遷移のみ抽出(次ページあり・同一遷移除外)
valid_transitions AS (
SELECT DISTINCT
REGEXP_REPLACE(page_location, r'^https?://[^/]+', '') AS trigger_page_path,
user_pseudo_id,
ga_session_id,
REGEXP_REPLACE(next_page, r'^https?://[^/]+', '') AS target_page_path
FROM page_views
WHERE page_location LIKE '%YOUR_TRIGGER_PAGE%' -- ★ 同じ条件
AND next_page IS NOT NULL
AND page_location != next_page
),
-- ⑤ 遷移先ごとのセッション数を集計
transition_counts AS (
SELECT
trigger_page_path,
target_page_path,
COUNT(DISTINCT ga_session_id) AS transitioned_sessions
FROM valid_transitions
GROUP BY trigger_page_path, target_page_path
)
-- ⑥ 出力(母数・遷移率を計算)
SELECT
t.trigger_page_path,
t.target_page_path,
t.transitioned_sessions,
b.total_trigger_sessions,
SAFE_DIVIDE(t.transitioned_sessions, b.total_trigger_sessions) AS transition_rate
FROM transition_counts t
JOIN (
SELECT trigger_page_path, COUNT(DISTINCT ga_session_id) AS total_trigger_sessions
FROM trigger_sessions
GROUP BY trigger_page_path
) b
ON t.trigger_page_path = b.trigger_page_path
ORDER BY t.transitioned_sessions DESC
LIMIT 100;
確認すべきポイント
- 対象の起点指定
YOUR_TRIGGER_PAGE
をパスで指定(例:/lp/campaign2025
)。クエリ差異を吸収したい場合は、前段でクエリ除去+小文字化(REGEXP_EXTRACT(LOWER(page_location), r'^https?://[^/]+([^?]+)')
)を推奨。 期間とタイムゾーン
期間フィルタが無いので、必要ならevent_date
由来の_TABLE_SUFFIX
条件を追加。Asia/Tokyo集計にするならTIMESTAMP
→DATETIME
変換で日付境界を合わせる。セッション粒度の揺れ
ga_session_id
の生成はGA4側ロジック依存。Consentやクロスデバイスでセッション分断が起きる点は前提として共有。外部/内部リンクの扱い
外部遷移は次ページがNULL
になりやすい(サイト外ログが無い)。内部導線評価に使う前提でOK。ページ階層の統合
/product/abc/?ref=...
など表記ゆれは事前正規化で吸収。末尾スラッシュや大文字小文字も統一を。ランキングの読み方
遷移率が高い=必ず良いではない。FAQ・利用規約への高遷移は「LP不足」を示唆する場合がある。文脈で解釈を。深掘り拡張
“次ページ”ではなく**“n手先”**(LEAD(..., n)
)を見る、流入別(traffic_source.medium
)でセグメントするなど拡張可能。
- 対象の起点指定
まとめ
このSQLを使うと、「特定ページからユーザーがどこへ進むのか」 を明確に把握できる。
起点ページからの“次の一歩”を、セッション集合の母数と並べて遷移率で比較できる。
LPや商品詳細、価格ページで強い導線/弱い導線がはっきりするため、CTA配置・FAQ内包・関連リンクの改善に直結。
URL正規化・期間/TZ・セッション粒度を押さえれば、毎週の改善会議で回せる定例レポートのコアになる。