我有一个BigQuery结果集,其中包含网站事件,可以按几列对事件进行分组和排序,其中包括时间戳记,事件类型和用户ID。
对于每个userId,我想按时间戳event_type_1
(登录)返回第一行,然后对于同一用户,返回event_type_2
(pageView)的第一行,但仅当{ {1}}> = event_type_2.timestamp
。重复六种事件类型,然后为所有用户返回结果。
我知道我可以使用命名子查询来完成此操作,例如WITH子句,如以下示例所示。但这是低效的,因为它会在每个对其的引用上运行子查询。 WITH语句中的子查询运行大约5秒钟,而整个查询则需要5秒钟的倍数,具体取决于子查询被引用的次数。
event_type_1.timestamp
我知道,如果我的唯一目标是更快的查询/更少的资源,则可以将子查询实现为临时BQ表或永久BQ表。但是我想知道窗口函数是否可以(按用户)按时间戳定位第一个WITH filtered_events AS
(
SELECT * FROM per_user_events ORDER BY userId, timestamp -- note: this is vastly simplified
),
event_type_1 as (
SELECT *
FROM filtered_events
WHERE filtered_events.type = 1),
event_type_2 as (
SELECT filtered_events.*
FROM filtered_events
INNER JOIN event_type_1 ON event_type_1.userId = filtered_events.userId
WHERE filtered_events.type = 2
AND filtered_events.timestamp >= event_type_1.timestamp),
event_type_3 as (
SELECT filtered_events.*
FROM filtered_events
INNER JOIN event_type_2 ON event_type_2.userId = filtered_events.userId
WHERE filtered_events.type = 3
AND filtered_events.timestamp >= event_type_2.timestamp),
event_type_4 as (
SELECT filtered_events.*
FROM filtered_events
INNER JOIN event_type_3 ON event_type_3.userId = filtered_events.userId
WHERE filtered_events.type = 4
AND filtered_events.timestamp >= event_type_3.timestamp)
SELECT * FROM event_type_1
UNION DISTINCT
SELECT * FROM event_type_2
UNION DISTINCT
SELECT * FROM event_type_3
UNION DISTINCT
SELECT * FROM event_type_4
ORDER BY userId, timestamp
,然后找到第一个event_type_1
,它在 timestamp1之后,然后第一个event_type_2
在timestamp2之后,等等。
我熟悉使用窗口函数event_type_3
为每个事件选择行的子集,但这无助于我跳过过去在 事件1之前的event2实例,因此,最终会根据每个用户对事件1->事件2->事件3进行所需的排序。