【前編】GA4とBigQueryのセッション数がなぜ違う?構造の違いとズレの要因を読み解く

GA4のレポート画面で見た流入元別のセッション数と、BigQueryにエクスポートされたデータを用いてSQLで集計したセッション数。この2つの数値が大きく異なることが気になっている方は多いのではないでしょうか。

本記事では、GA4画面の数値とBigQueryにエクスポートされた数値の違いを解説し、セッション数のズレが発生する原因を整理します。

次回予告:後編では、実際にGA4のUIに近い数値をBigQueryで再現するためのSQLテンプレートを公開します。

1. GA4画面とBigQuery上のデータ構造の違い

GA4のレポート画面に表示される数値は、サンプリング処理やしきい値処理、さらには自動チャネルグループ分類など、さまざまなレイヤーで加工されています。一方、BigQueryで扱うデータはイベント単位での“生データ”であり、整形や集計処理はユーザー側に委ねられます。

そのため、見えている数値の“前提”がそもそも異なることに注意が必要です。

2. セッションの定義とカウント方法の違い

GA4画面でのセッションのカウントは、session_start イベントの発生をセッション開始の最も直接的な指標としていますが、ユーザーの非アクティブ状態からの再開や、新しいキャンペーンソースからのアクセスも新しいセッションをトリガーする要因としています。

BigQueryでは、セッションIDを基にセッション単位の集計が可能ですが、どのイベントを起点にするか/どのフィールドを用いるかによって数値が大きく変動します。

参考:GA4画面のセッションに相当するフィールド

  • event_name = 'session_start'
  • ga_session_id(event_params 内)
  • traffic_source.* または session_traffic_source_last_click.*(2024年7月以降)

3. ズレの主な原因とそれぞれの説明

セッション数のズレには、いくつかの代表的な要因があります。それぞれについて、仕組みと注意点を詳しく説明します。

(1)ダイレクト再訪時の流入元の引き継ぎ

GA4画面上のデータには、いわゆる「ラストノンディレクトクリック」モデルが適用されています。これは、ユーザーが一度非ダイレクトチャネル(検索、広告、SNSなど)から訪問したあと、次にダイレクト(ブックマークやURL直打ち)で訪れた場合、前回の流入元を引き継いで表示する仕様です。

一方BigQueryでは、traffic_source.*フィールドに「(direct) / (none)」が記録され、過去の流入元は参照されません。GA4 UIと同様の流入元の引き継ぎを再現するには、ユーザー単位で履歴を追うロジックが必要になります。

補足:2024年7月17日以降のデータには session_traffic_source_last_click が追加され、引き継ぎ後の流入元をそのまま参照可能になりました。

(2)しきい値適用(Thresholding)

GA4画面のデータには、一定の条件下でデータの一部がマスキングされる「しきい値処理」が実行されます。特にユーザー識別子やセンシティブな情報が含まれる場合、表示が制限されることがあります。

一方、BigQueryではこの制御は一切行われず、条件を満たすすべてのイベントデータが取得されます。 そのため、UIに比べて過大に見えることもあります。

(3)サンプリング

GA4の探索レポートや特定のカスタムビューでは、一部のデータがサンプリング処理されることがあります。 特に大量のデータや複雑なディメンションが含まれる場合に起こりがちです。

BigQueryのデータは、基本的にサンプリングなしのフルデータエクスポートであるため、この点でも数値に差が出る原因となります。

(4)チャネルグループ分類の差異

GA4 UIでのチャネル分類(例:Organic Search、Paid Socialなど)は、自動的にsource / mediumに基づいて分類される「default channel group」が適用されています。

BigQueryにはこの分類は存在しないため、同様のチャネル分けを行うには、独自のCASE文でsourceとmediumを再分類する必要があります。

この再分類ロジックについては、以下の記事で詳しく解説しています:
GA4チャネルグループ分類の正規表現まとめ|BigQuery用サンプルSQLつき

(5)セッション定義の再現不足

BigQueryでGA4のセッションを集計する際には、一般的に ga_session_idsession_start イベントを使いますが、これらの情報だけに頼っていると、1回の訪問が複数のセッションとして扱われてしまうことがあります。

たとえば、次のようなケースです:

  • session_start イベントが記録されておらず、セッションの起点が不明
  • イベントデータの一部がログとして残っていない(計測の抜け)
  • イベントとイベントの間に30分以上の空白がある

このような場合、本来はひとつの訪問であっても、BigQuery上では「セッションが分断されたように見える」ことがあります。
GA4の画面ではセッションのルール(30分ルールなど)が自動で適用されますが、BigQueryにはこれがないため、自力で再現しなければなりません。

そのため、セッションを集計する際は イベントの時系列や欠損状況を考慮した再構築ロジックが重要になります。

📝 意味がわかりにくかったあなたと私のための補足(それでも難しいけど…)

※セッションの再現には、event_timestamp をもとにした「30分ルールによるグルーピング」や、session_start の有無チェックがよく使われます。データの抜けやイベント間隔によって、セッションの判定がずれることがある点には注意が必要です。

4. ズレ要因をどう扱うべきか(指標運用方針)

実務上は「ズレがあることを前提に設計する」ことが現実的です。

  • マーケティング施策の効果測定にはGA4のデータを使う(ラストノンディレクトモデルが自動適用されるため)
  • 施策全体の傾向把握やローデータ分析にはBigQueryのデータを使う
  • SQLで再現できる範囲を社内で明示し、運用ルール化する

後編では、GA4画面の数値に近いセッション数をBigQueryで再現するSQLを具体的に紹介します。

脚注:GA4 UIとBigQueryフィールドの対応表(一部)

GA4 UI上の名称BigQuery上のフィールド
セッション数event_name = 'session_start' のカウント
流入元 / メディアtraffic_source.source / traffic_source.medium(または session_traffic_source_last_click.*
チャネルグループ自作CASE文による再分類が必要

本記事は前編です。補正ロジックや実装SQLにフォーカスした後編はこちら:
👉 GA4×BigQuery セッションのズレを補正する実践ガイド|チャネル再現とSQL実装のポイント


📌 この記事は、GA4 × BigQuery の実務分析を支援する「サイトウオンライン」の実験室よりお届けしました。