在Snowflake SQL中基于DateTime构建会话逻辑

问题描述 投票:0回答:1

我正在尝试基于一组列(如 Userid、DeviceId)的 DateTime 值构建会话逻辑

对于给定的用户 ID、设备 ID,会话可以在一天中的任何时间(第一个事件)开始,并且该小时内发生的所有事件都需要有一个会话 ID。

WITH CTEA AS (
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 01:01:00' AS EVENTDATETIME UNION ALL
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 01:02:00' UNION ALL
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 02:01:00' UNION ALL
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 02:01:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 01:03:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 01:04:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 02:05:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 02:06:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 02:01:00' UNION ALL
SELECT 1 AS USERID, 200 AS DEVICEID , '2024-05-02 03:02:00' 
)

SELECT * FROM CTEA
;

期望的结果:

> USERID    DEVICEID    EVENTDATETIME        SESSIONID(ANY NUMBER)
>     1       100   2024-05-02 01:01:00   200
>     1       100   2024-05-02 01:02:00   200
>     1       100   2024-05-02 02:01:00   201 
>     1       100   2024-05-02 02:01:00   201
>     2       200   2024-05-02 01:03:00   202
>     2       200   2024-05-02 01:04:00   202
>     2       200   2024-05-02 02:05:00   203
>     2       200   2024-05-02 02:06:00   203
>     2       200   2024-05-02 02:01:00   203
>     1       200   2024-05-02 03:02:00   204

我能够通过循环实现,我正在寻找更高效的方法(自连接/窗口函数)。 如果有人对此有想法,请帮忙。

sql snowflake-cloud-data-platform logic window-functions self-join
1个回答
0
投票

尝试使用 TIME_SLICE 函数,这是一个示例:

WITH CTEA AS (
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 01:01:00' AS EVENTDATETIME UNION ALL
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 01:02:00' UNION ALL
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 02:01:00' UNION ALL
SELECT 1 AS USERID, 100 AS DEVICEID , '2024-05-02 02:01:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 01:03:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 01:04:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 02:05:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 02:06:00' UNION ALL
SELECT 2 AS USERID, 200 AS DEVICEID , '2024-05-02 02:01:00' UNION ALL
SELECT 1 AS USERID, 200 AS DEVICEID , '2024-05-02 03:02:00' 
)
SELECT USERID, DEVICEID, EVENTDATETIME
     , TIME_SLICE(EVENTDATETIME::DATETIME, 1, 'HOUR', 'START') AS TIME_SLICE_START
     , TIME_SLICE(EVENTDATETIME::DATETIME, 1, 'HOUR', 'END') AS TIME_SLICE_END
     , DENSE_RANK() OVER(ORDER BY TIME_SLICE_START, TIME_SLICE_END, USERID, DEVICEID) AS SESSIONID
  FROM CTEA
 ORDER BY EVENTDATETIME, USERID, DEVICEID;
© www.soinside.com 2019 - 2024. All rights reserved.