我正在尝试基于一组列(如 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
我能够通过循环实现,我正在寻找更高效的方法(自连接/窗口函数)。 如果有人对此有想法,请帮忙。
尝试使用 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;