我有一个存储userid、sessionid和datetime的表。该表存储用户登录到设备时的数据,并存储用户、会话和日期时间。一个userid和sessionid组合可以有多个条目。例如:
USERID | SESSIONID | DATE
abcd | 1234 | 2020-05-14 10:30:00
abcd | 1234 | 2020-05-14 10:32:00
abcd | 1234 | 2020-05-14 10:35:00
abcd | 1234 | 2020-05-14 11:32:00
abcd | 1234 | 2020-05-14 11:39:00
我正在尝试将这些行合并到一个新表中,该表基于同一会话和用户的initialdatetime-up-datetime+x。如果日期超过datetime+x,则初始datetime将移动。因此,如果x是30分钟,从开始到结束的任何日期时间+30分钟将是一行。如果一个日期大于datetime+30min,它将成为新的开始datetime,您将执行datetime+x,直到查看了sessionid和userid组合的所有日期。
示例表的输出应为:
USERID | SESSIONID | START_SESSION_DATE | END_SESSION_DATE
abcd | 1234 | 2020-05-14 10:30:00 | 2020-05-14 10:35:00
abcd | 1234 | 2020-05-14 11:32:00 | 2020-05-14 11:39:00
我不知道如何只用sql来实现这一点。我本来打算创建一个存储过程来执行javascript中的所有逻辑,然后在snowflake中插入到新表中,但这将非常缓慢,而且无法扩展。提前谢谢。
2条答案
按热度按时间mitkmikd1#
这有点棘手。您不能只比较相邻的行:您需要跟踪每个行序列的开始日期,以便可以将其与以下日期进行比较,并决定何时划分为新组。
这需要某种迭代过程。在sql中,这通常是通过递归查询实现的,幸运的是,snowflake支持递归查询
考虑:
第一个公共表表达式(
data
)枚举具有相同userid
以及sessionid
与row_number()
. 然后,第二个cte(cte
)迭代地遍历行组,从第一个行开始,并根据需要创建新的组。最后一步是聚合。ippsafx72#
此方法利用了雪花宽度_bucket函数,根据我生成的一些测试数据,似乎工作正常: