GA4

【GA4 SQL】UA定義の直帰率をBigQueryで再現

GA4のデフォルトの直帰率はエンゲージメント率の逆数であり、ユニバーサル アナリティクス(UA)の直帰率とは異なるものとなっている。UAの直帰率はランディングページから次ページへ遷移せずに離脱した割合のことを指す。UAも過去の産物となり、UA定義の直帰率の馴染み深さもなくなっていくかもしれないが、ランディングページのみの1ページのみで離脱したという定義はGA4になってもサイト分析に大いに活用できるものであるため、エンゲージメント率の逆数という同義の指標とは別に、いつでもUA定義の直帰率を指標として扱えるようにしておいた方がよいだろう。UAの直帰率の定義について公式ヘルプにおける記載は以下を参照。

参考:直帰率 -アナリティクス ヘルプ

より厳密にUA定義の直帰率を算出

UAにおける直帰とは、セッションの中で1ページしか閲覧されなかった場合に直帰とみなされる。このような直帰率を集計する際、よくセッションの中でpage_viewイベントが1か、それ以上かを判定しているのをみかけるが、単純にpage_viewイベントがセッションの中で1か否かを直帰の判定基準としてしまうと、1ページの中で複数回page_viewイベントが付いた場合には直帰判定とはならなくなる問題点が生じる。通常、同一ページでpage_viewイベントが複数回カウントされたとしても、同じページであればページ遷移とみなさないと考えるのが普通であるし、同一ページでpage_viewイベントが複数回カウントされ、離脱した場合は直帰としてカウントするべきである。

問題点を解決した唯一の直帰率の算出方法を開発

これまで述べたように同一ページの中のpage_viewイベントを「ページ遷移」とみなさない処理をする必要があるが、その方法について他で解説しているのを見たことがないため、当記事で解説する直帰率の算出方法が唯一、正確かつ厳密な直帰率を計算できる方法であるといえる。この正しい直帰率の計算方法により、同一ページの複数回のpage_viewイベントをページ遷移とみなし直帰とはみなさない方法と比べて、直帰率は上がるものと想定されるが、本来の正しい直帰率となる。

再帰CTEによる次ページの取得【非推奨】

※追記(24年07月30日)再帰CTEによる処理は再帰処理が500を超えるとエラーが生じるため、以下再帰クエリは非推奨。改良版を作成したため、さらに下部を参照。

別記事でも既に解説したが、次ページが見つかるか離脱するまでに再帰的な処理により直帰判定を行っている。つまりセッションの中で、同一ページを除く次の遷移先ページが見つからなければ直帰となる。これにより正確に直帰率の判定が可能になる。

参考:再帰 CTE を使用する -Google Cloud

再帰CTEによるUA定義の直帰率を算出するクエリ

※こちらの再帰CTEのコードは非推奨
CREATE TEMP FUNCTION date_from() RETURNS STRING AS ('20240401');

WITH RECURSIVE
  SessionData AS (
    SELECT
      ssid,
      ymd,
      event_timestamp,
      page_location,
      LEAD(page_location) OVER(PARTITION BY ssid ORDER BY event_timestamp ASC) AS next_page_location,
      LEAD(event_timestamp) OVER(PARTITION BY ssid ORDER BY event_timestamp ASC) AS next_event_timestamp,
      entrances,
      1 AS depth
    FROM (
      SELECT
        CONCAT(user_pseudo_id, '-', CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS STRING)) AS ssid,
        PARSE_DATE("%Y%m%d", event_date) AS ymd,
        event_timestamp,
        REGEXP_REPLACE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location'), r"\?.*", "") AS page_location,
        (SELECT value.int_value FROM UNNEST(event_params) p WHERE p.key = 'entrances') AS entrances
      FROM
        `<project>.<dataset>.events_*`
      WHERE
         _TABLE_SUFFIX BETWEEN date_from() AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
        AND
          event_name = 'page_view'
    )
  ),
  RecursivePages AS (
      SELECT
        ssid,
        ymd,
        event_timestamp,
        page_location,      
        next_page_location,
        next_event_timestamp,
        entrances,
        depth
      FROM
        SessionData
    UNION ALL
      SELECT
        rp.ssid, 
        rp.ymd,
        rp.event_timestamp,
        rp.page_location,
        sd.next_page_location, 
        sd.next_event_timestamp,
        rp.entrances,
        rp.depth + 1
      FROM
        RecursivePages rp
      INNER JOIN
        SessionData sd
      ON
          rp.ssid = sd.ssid
        AND
          rp.ymd = sd.ymd
        AND
          rp.next_event_timestamp = sd.event_timestamp
      WHERE
        rp.page_location = rp.next_page_location 
  ),
  Master_01 AS (
    SELECT
      ssid,
      ymd,
      event_timestamp,
      page_location AS Landing_page,
      CASE
        WHEN next_page_location IS NULL THEN 'Exit'
        ELSE next_page_location
      END AS final_next_page,
      entrances
    FROM
      RecursivePages
    WHERE (
      page_location != next_page_location
    OR
      next_page_location IS NULL
    )
    AND
      entrances = 1
    ORDER BY
      page_location,
      ymd
  ),
  CalcBounce_01 AS (
    SELECT
      ymd,
      Landing_page,
      IF(final_next_page = 'Exit',1, 0) AS _exit,
      entrances AS _entrances
    FROM
      Master_01
  ),
  CalcBounce_02 AS (
    SELECT
      Landing_page,
      SUM(_exit) AS _exit,
      SUM(_entrances) AS _entrances,
      ROUND( (SUM(_exit) / SUM(_entrances) * 100), 1) AS _BounceRate
    FROM
      CalcBounce_01
    GROUP BY
      Landing_page
  )

SELECT
  *
FROM
  CalcBounce_02

クエリ解説

直帰率の計算結果までをBigQuery内で表示させるために計算結果まで求めているが、通常はこのような割合の計算はBIツール側で行う。その際は1つ前のCTEである「CalcBounce_01」までのクエリ結果を求めBIツールと連携し直帰率を求める。

新規ユーザーの直帰率を算出するクエリ

ここでの新規ユーザーの定義は、初回訪問したその日のセッションは全て初回訪問扱いとしている。新規ユーザーについては別記事にて解説済み

Protected Area

This content is password-protected. Please verify with a password to unlock the content.

UA定義の直帰率を算出するクエリ【改良版】

UAの直帰率の定義と同様の1セッションの中で1ページビューのみであったセッションを直帰とみなす。

CREATE TEMP FUNCTION date_from() RETURNS STRING AS ('20240401');

WITH
  BounceRate AS (
    SELECT
      ymd,
      Landing_page,
      IF(final_next_page = 'Exit',1, 0) AS _exit,
      _entrances
    FROM (
      SELECT
        ssid,
        ymd,
        event_timestamp,
        page_location AS Landing_page,
        CASE
          WHEN next_page_location IS NULL THEN 'Exit'
          ELSE next_page_location
        END AS final_next_page,
        IF ( 
            entrances = 1
          OR
            entrances_01 = 1
          ,1,0
        ) AS _entrances
      FROM (
        SELECT
          *,
          IF ( 
              LAG(entrances) OVER(PARTITION BY ssid ORDER BY event_timestamp ASC) = 1
            AND
              LAG(dup_page) OVER(PARTITION BY ssid ORDER BY event_timestamp ASC) = 1
            ,1,0
          ) AS entrances_01
        FROM (
          SELECT
            ssid,
            ymd,
            event_timestamp,
            page_location,
            next_page_location,
            IF(page_location = next_page_location,1, 0) AS dup_page,
            entrances
          FROM (
            SELECT
              ssid,
              ymd,
              event_timestamp,
              page_location,
              LEAD(page_location) OVER(PARTITION BY ssid ORDER BY event_timestamp ASC) AS next_page_location,
              entrances
            FROM (
              SELECT
                CONCAT(user_pseudo_id, '-', CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS STRING)) AS ssid,
                PARSE_DATE("%Y%m%d", event_date) AS ymd,
                event_timestamp,
                REGEXP_REPLACE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location'), r"\?.*", "") AS page_location,
                (SELECT value.int_value FROM UNNEST(event_params) p WHERE p.key = 'entrances') AS entrances
              FROM
                `<project>.<dataset>.events_*`
              WHERE
                _TABLE_SUFFIX BETWEEN date_from() AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
              AND
                event_name = 'page_view'
            )
          )
        )
        WHERE
          entrances = 1
        OR
          dup_page = 0 
      )
      WHERE
        (dup_page = 0 AND entrances = 1)
      OR
        entrances_01 = 1
    )

  )

SELECT
  *
FROM
    BounceRate

関連記事

【検証】batch_page_id パラメータとは

【検証】GA4 entrancesパラメータ

【GA4SQL】最新のページタイトル(page_title)を取得

PAGE TOP