我在PostgreSQL中有一个带有时间戳列created_at
和整数列user_id
的表。
id | created_at | user_id
1 | 2019-10-14 09:26:53.813 | 1
2 | 2019-10-14 09:26:54.813 | 1
3 | 2019-10-14 09:46:53.813 | 1
4 | 2019-10-14 09:46:54.813 | 2
5 | 2019-10-14 09:46:55.813 | 1
6 | 2019-10-14 09:46:56.813 | 1
7 | 2019-10-14 09:46:57.813 | 2
每行代表用户的某些操作。我需要计算平均用户会话长度。会话定义为时间差小于10分钟的一组动作。如果两个用户操作之间相差10分钟或更长时间,则新会话开始。
我在想:
user_id
对行进行分组。但是我不能用SQL编写它。
能否给我一些建议/示例,如何在SQL中完成?
答案 0 :(得分:1)
使用yourString.split('__SEPARATOR__')[2].lstrip("'")
以及差异超出阈值的累积计数:
lag()
答案 1 :(得分:0)
SELECT
user_id,
AVG(diff)
FROM (
SELECT DISTINCT
user_id,
group_id,
first_value(created_at) OVER (PARTITION BY user_id, group_id ORDER BY created_at DESC)
- first_value(created_at) OVER (PARTITION BY user_id, group_id ORDER BY created_at) as diff
FROM (
SELECT
id, created_at, user_id,
SUM(group_id) OVER (PARTITION BY user_id ORDER BY created_at) AS group_id
FROM (
SELECT
*,
(created_at
- lag(created_at, 1, created_at) OVER (PARTITION BY user_id ORDER BY created_at)
> interval '10 minutes')::int AS group_id
FROM
mytable
)s
)s
)s
GROUP BY user_id
(created_at - lag(created_at, 1, created_at) OVER (PARTITION BY user_id ORDER BY created_at) > interval '10 minutes')::int AS group_id
:lag()
window function从上一个记录中获取created_at
的值(第二个参数:步长,第三个参数:如果没有上一个记录,则为默认值==当前值)在有序user_id
分区(组)中。然后,计算当前created_at
值与前一个值之间的差。如果该值> 10分钟,则结果为true
; false
否则。可以将该布尔值转换为int
值,从而产生0
或1
SUM()
/ 0
值上累积1
,每个group_id
的每个新会话都会产生user_id
s user_id
和会话group_id
的第一个created_at时间戳可以通过first_value()
窗口函数来获取,最后一个first_value()
和DESC
来获取。不同之处在于您每次会话的时长。之所以使用DISTINCT
子句,是因为差异值被放入每个记录中。但是我们只需要一次。AVG()
进行区别。