Redshift:在没有任何会话ID的情况下查找会话中的第一个和最后一个事件
Posted
技术标签:
【中文标题】Redshift:在没有任何会话ID的情况下查找会话中的第一个和最后一个事件【英文标题】:Redshift: Finding first and last events in session without any session id 【发布时间】:2018-10-02 12:38:30 【问题描述】:我有一个移动应用中用户事件的 Redshift 表:
|user| screen |collector_timestamp|
---------------------------------------
|1111| StartScreen|2018-10-01 07:02:33|
|1111|FinishScreen|2018-10-01 07:02:34|
|1112| OrderScreen|2018-10-01 07:10:33|
|1113| StartScreen|2018-10-01 09:01:27|
会话 - 连续事件之间的间隔小于 1 小时时的活动。
我想找到一个会话(第一个和最后一个 collector_timestamp
),其中用户访问 0 个或多个任意屏幕,然后是 StartScreen
,然后是 0 个或多个任意屏幕,然后是 OrderScreen
,然后是 0 个或多个任意屏幕,然后是FinishScreen
。
当我尝试应用三重自联接时,permission denied to create temporary tables in database
出现错误,因为联接的结果不会在内存中存储。
我还能如何找到合适的课程?
【问题讨论】:
你的问题似乎比你的标题更广泛,所以我对你的问题感到困惑。 @GordonLinoff 我改写了标题 除了 StartScreen、FinishScreen 和 OrderScreen 之外,“screen”还有其他可能的值吗?我认为您需要提供更大的示例数据集来说明问题。 @Nathan 是的,还有其他屏幕。 【参考方案1】:首先使用 Redshift 中的 LAG
窗口函数创建会话 ID。
然后仅使用您关心的屏幕聚合会话中的有序事件。使用它,您可以过滤出您正在寻找的确切模式。该示例在一个查询中执行此操作,但实际上可能应该使用多个表来完成,以便您可以参考每个会话的详细数据。以下代码使用您提供的数据在 Redshift 中构建了一个自包含示例,并带有一些额外的记录来演示结果。
DROP TABLE IF EXISTS events;
CREATE TABLE events
("user" INT
, "screen" VARCHAR(12)
, "collector_timestamp" TIMESTAMP
);
INSERT INTO events
("user", "screen", "collector_timestamp")
VALUES
(1111, 'StartScreen', '2018-10-01 07:02:33'),
(1111, 'FinishScreen', '2018-10-01 07:02:34'),
(1112, 'OrderScreen', '2018-10-01 07:10:33'),
(1113, 'StartScreen', '2018-10-01 09:01:27'),
(1112, 'StartScreen', '2018-10-01 09:10:33'),
(1112, 'OrderScreen', '2018-10-01 09:11:33'),
(1112, 'FinishScreen', '2018-10-01 09:12:33')
;
WITH sessionized_events AS(
SELECT *
, "user"||'_'|| SUM(new_session) OVER (PARTITION BY USER ORDER BY collector_timestamp ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS session_id
FROM(
SELECT
*
, CASE
WHEN EXTRACT(EPOCH FROM collector_timestamp)
- LAG(EXTRACT(EPOCH FROM collector_timestamp))
OVER (PARTITION BY "user" ORDER BY collector_timestamp) >= 60 * 60
THEN 1
ELSE 0
END AS new_session
FROM events
) s
)
SELECT
session_id
FROM sessionized_events
GROUP BY 1
HAVING listagg(DISTINCT screen)
WITHIN GROUP (ORDER BY collector_timestamp) like ('%StartScreen%OrderScreen%FinishScreen')
;
结果:
session_id
----------
1112_1
Postgres 的语法与 Redshift 不同,但对于那些没有 Redshift 集群来运行它的人,我在 SQLFiddle here 上有一个示例。
【讨论】:
以上是关于Redshift:在没有任何会话ID的情况下查找会话中的第一个和最后一个事件的主要内容,如果未能解决你的问题,请参考以下文章
在不使用 aws 凭据的情况下连接 Redshift 和 Python(在 emr 上运行)
已发布的应用程序显示“无法在没有验证证明、会话信息、临时证明或注册 ID 的情况下创建 PhoneAuthCredential。”