我正在尝试添加另一个名为 session_id 的列。我想根据date_time之间的时间差超过30分钟的条件进行排名,那么这将被视为另一个会话。这是我正在尝试做的一个例子:
日期差异 | 日期_时间 | session_id |
---|---|---|
0 | 2023-01-18 00:01:40.000000 | 1 |
0 | 2023-01-18 00:01:42.000000 | 1 |
0 | 2023-01-18 00:01:46.000000 | 1 |
93 | 2023-01-18 01:34:38.000000 | 2 |
0 | 2023-01-18 01:34:38.000000 | 2 |
27 | 2023-01-18 02:01:59.000000 | 2 |
1 | 2023-01-18 02:02:00.000000 | 2 |
89 | 2023-01-18 03:31:40.000000 | 3 |
所以只要 date_diff 分钟数超过 30,就会被归类为新会话。
在 Redshift 中可能有更好的方法来做到这一点,我没有,但你可以尝试这样的事情:
SELECT Datetime, date_diff,
SUM(CASE WHEN date_diff > 30 THEN 1 ELSE 0 END) OVER (ORDER BY Datetime) AS group_id
FROM your_table
这只是用 1 标记行 > 30,然后
OVER()
子句将排序和求和,这将创建您要查找的有序 session_id。
一个选项使用条件窗口和:
select t.*,
1 + sum(case when date_diff > 30 then 1 else 0 end)
over(order by date_time) session_id
from mytable
如果您想根据时间戳列动态计算日期差异,我们将首先使用
lag()
:
select t.*,
1 + sum(case when datediff(minute, lag_date_time, date_time) > 30 then 1 else 0 end)
over(order by date_time) session_id
from (
select t.*, lag(date_time, 1, date_time) over(order by date_time) lag_date_time
from mytable t
) t
您可以使用 SQL 中的窗口函数来实现此目的。假设您有一个名为 activity 的表,其中包含 date_diff 和 date_time 列,您可以使用以下查询来计算 session_id:
WITH
time_diffs AS (
SELECT
*,
LAG(date_time) OVER (ORDER BY date_time) AS prev_date_time
FROM
activity
),
flagged_sessions AS (
SELECT
*,
CASE
WHEN EXTRACT(EPOCH FROM (date_time - prev_date_time)) / 60 > 30 THEN 1
ELSE 0
END AS new_session_flag
FROM
time_diffs
),
session_ids AS (
SELECT
*,
SUM(new_session_flag) OVER (ORDER BY date_time) + 1 AS session_id
FROM
flagged_sessions
)
SELECT
date_diff,
date_time,
session_id
FROM
session_ids
ORDER BY
date_time;
在此查询中:
我们首先使用 time_diffs CTE 中的 LAG 窗口函数计算当前行与上一行之间的时间差。 然后,我们在 flagged_sessions CTE 中创建一个 new_session_flag 列,如果时差超过 30 分钟则为 1,否则为 0。 最后,我们通过对 new_session_flag 列求和并在 session_ids CTE 中将其加 1 来计算 session_id。 最终结果是从 session_ids CTE 中选取的,并按 date_time 排序。