我有一个包含4列的表格:hitId,userId,timestamp和Camp。 我需要使用两个参数对点击是否是新会话的开始(1或0)进行分类:1.点击之间的时间差; 2。如果点击的来源是新的广告系列。
我需要BigQuery中的标准SQL查询。
如果满足以下条件之一,则将匹配视为新会话的开始:
因此,如果用户1的hit1的Camp等于Campaign1,用户1的hit2的Camp等于Campaign1,并且hit1和hit2之间的时间差小于30分钟,则hit1将被视为会话的开始,并且hit2不会被视为一个开始。
我在Campaign部分遇到了麻烦。我尝试了这段代码:
我尝试了以下代码:
WITH timeDifference AS (
SELECT *,
TIMESTAMP_DIFF(timestamp, LAG(timestamp, 1) OVER
(PARTITION BY userId ORDER BY timestamp), SECOND) AS difference
FROM hitTable
ORDER BY timestamp)
SELECT *,
CASE
WHEN difference >= 30 * 60 THEN 1
WHEN difference IS NULL THEN 1
WHEN difference <= 30 * 60 AND Camp IS NOT NULL AND RANK()
OVER (PARTITION BY userId ORDER BY Camp) = 1 THEN 1
ELSE 0 END AS sess
FROM timeDifference
ORDER BY timestamp;
当我收到此表时,条件RANK() OVER (PARTITION BY userId ORDER BY Camp)
似乎不起作用:
hitId | userId | timestamp | Camp | difference | sess
_______________________________________________________________________
00150 | 858201 | 00:48:35.315 | NULL | NULL | 1
00151 | 858201 | 00:49:35.315 | NULL | 5 | 0
00152 | 858201 | 00:50:35.315 | Search-Ads-US | 10 | 0
00153 | 858201 | 00:53:35.315 | Search-Ads-US | 15 | 0
00154 | 858202 | 00:54:35.315 | Facebook-Ads | NULL | 1
00155 | 858202 | 00:54:55.315 | Facebook-Ads | 9 | 0
00156 | 858202 | 00:57:20.315 | Facebook-Ads | 12 | 0
虽然我希望hitId = 00152的sess
列有1:
hitId | userId | timestamp | Camp | difference | sess
_______________________________________________________________________
00150 | 858201 | 00:48:35.315 | NULL | NULL | 1
00151 | 858201 | 00:49:35.315 | NULL | 5 | 0
00152 | 858201 | 00:50:35.315 | Search-Ads-US | 10 | 1
00153 | 858201 | 00:53:35.315 | Search-Ads-US | 15 | 0
00154 | 858202 | 00:54:35.315 | Facebook-Ads | NULL | 1
00155 | 858202 | 00:54:55.315 | Facebook-Ads | 9 | 0
00156 | 858202 | 00:57:20.315 | Facebook-Ads | 12 | 0
答案 0 :(得分:0)
在用户具有多个Camp的情况下,此RANK()OVER(PARTITION BY userId或ORDER BY Camp)返回错误的结果。
请注意,当您要标记每个Camp中的会话时,您的PARTITION BY使用userId。
userId 00150的RANK()(...)语句的实际“等级1”是Camp为NULL(hitId 00150)的位置,因此它缺少您在hitId 00152的CASE条件。
您可以尝试将“ Camp”添加到您的PARTITION BY中,如下所示: RANK()OVER(PARTITION BY userId,Camp ORDER BY Camp)
或者,您可以替换RANK()(...)并使用LAG(Camp)(...按时间戳排序),而不要计算LAG(timestamp)(...)。 这将检索之前行的Camp值(称为“ PreviousCampValue”)。然后,您可以添加类似WHEN PreviousCampValue!= Camp THEN 1
希望有帮助