从GA4的落地页为not set说起
GA4有两个好朋友,一个是Looker Studio,另一个是BigQuery。
没有这两个工具加持GA4就是辣鸡中的战斗机。
- Looker Studio的友好度比BigQuery要高许多,因为其预定义了许多维度和指标,它们和GA4一致。
- 但是BigQuery并不是这样。GA4导出到BigQuery的数据非常生,好处是能帮我们更好地理解封装好的维度和指标的意义,坏处是加工太难。
于是BigQuery又有了另一个好朋友GA4SQL.com。可以帮助我们写复杂的SQL。
举个例子,我们打开ga4sql.com。

填入我们连接好的BigQuery数据库表名,然后傻瓜式地填上Metrics和Dimensions,按个Generate Query按钮就可以立即生成复杂的SQL脚本。脚本甚至贴心地将GA4默认的一些bug补上了,你看这Session Channel的定义便知。接着将脚本贴到BigQuery中跑一下就直接能出结果。
如果GA4就这么简单的话马老师写到这里就结束了,文章将欢天喜地地以“连小白都能从容驾驭GA4”结尾。可实际上并不这么简单。
你可以试试看做这样一个报表,就是落地页流量报表。Dimension只有一个Landing Page,而Metric也只有一个Sessions。
看似简单的需求,看似简单的报表在GA4中实际上炒鸡炒鸡复杂。就拿落地页Landing Page来说,它需要去找session_start事件的page_location。(马老师假定你读过了上一篇《为什么说GA4的session_start是一个寄生事件》)Sessions也不简单,它需要将user_pseudo_id和ga_session_id放在一起去重。
在Looker Studio中,Landing Page是已经帮大家封装好的,Sessions也是。即便是这样,当你拉出报表来后,不可避免地会看到许多落地页为(not set)的结果行。比如下图的情况
先放一边,我们回到ga4sql.com,尝试生成sql再去跑一下。同样会看到Landing Page为null。而且即便日期调整一致了这两边也是对不上的。
所以讲到这里极诣的读者要问了,为什么会出现这些情况,如何修复。
出现这个现象的原因在Looker Studio和Bigquery中不尽相同。
Looker Studio的Landing Page和GA4中完全一致,因此仅当一个Session的第一个一般事件是PageView时才将该session_start中的page location记作Landing Page。
因此当一个页面放置了很久却没有关闭,会话过期后再来关闭时会产生一个新的session,此时并没有先触发一个page_view事件。那么这个时候landing page就会是(not set)。所以对我们研究落地页来说大可以忽略这些流量,不必进行修复。如果非要进行干预,那么可以使用event_name和page_location作为Dimension,将event count作为metrics,然后过滤event name=session_start。
另一方面,在BigQuery中的现象我们需要深入SQL脚本来理解。下面是ga4sql.com给出的SQL脚本:
/* This query is generated by ga4Sql.com */
SELECT
landing_page,
COUNT(DISTINCT session_id) AS sessions
FROM
(
SELECT
MAX(
(
SELECT
value.string_value
FROM
UNNEST (event_params)
WHERE
event_name = 'session_start'
AND key = 'page_location'
)
) AS landing_page,
CONCAT(
user_pseudo_id,
(
SELECT
value.int_value
FROM
UNNEST (event_params)
WHERE
key = 'ga_session_id'
)
) AS session_id
FROM
`your_project.analytics_xxxxxxxxxx.events_*`
WHERE
_TABLE_SUFFIX BETWEEN '20231101' AND '20231116'
GROUP BY
session_id
)
GROUP BY
landing_page
之所以出现有null的Landing Page是因为存在一些session_id这些Session没有session_start事件。所以MAX那段就找不到对应的landing_page。
我们看导出到BigQuery的数据可以发现所有的事件都是含有page_location属性的,因此不存在丢失了page_location的session_start的说法。而且我们强调过,session_start是一个寄生事件。
马老师对这部分的事件出现原因并不清楚,排除了跨天可能后怀疑可能是机器人干扰或者前端对于某些事件的屏蔽。不过因为这部分比例极低,我们依旧可以直接忽略。实在不想忽略,可以参照下面这个脚本:
/* This query is generated by ga4Sql.com */
SELECT
event_name,
page_location,
SUM(event_count) AS event_count
FROM
(
SELECT
event_name AS event_name,
(
SELECT
value.string_value
FROM
UNNEST (event_params)
WHERE
event_name = 'session_start'
AND key = 'page_location'
) AS page_location,
COUNT(event_name) AS event_count
FROM
`your_project.analytics_xxxxxxxxxx.events_*`
WHERE
_TABLE_SUFFIX BETWEEN '20231101' AND '20231116'
GROUP BY
event_name,
page_location
)
GROUP BY
event_name,
page_location
HAVING
event_name = 'session_start'
所以说了那么多,重点和结论是?
- GA4的各种维度和指标的定义和以往有很大不同,不管是老手还是新手都需要谨慎使用。
- 一些无法解释的数据背后是数据处理和数据异常,要想了解根本原因只有下到Raw data本身。
- 对于BigQuery的Event表Schema我们要非常熟悉才能帮助我们理解数据和解决问题。
- 同一道题可能有多种解法,不必追求一次解出,可以允许对过程数据再加工避免错误。