我在postgres表的日志表中有以下数据:
以下是存储在表格中的数据(其中实际开始时间不是列,只是以24小时格式显示UTC格式的start_time值)
logid user_id start_time inserted_value start time actual
1 1 1518416562 15 12-Feb-2018 06:22:42
2 1 1518416622 8 12-Feb-2018 06:23:42
3 1 1518417342 9 12-Feb-2018 06:35:42
4 1 1518417402 12 12-Feb-2018 06:36:42
5 1 1518417462 18 12-Feb-2018 06:37:42
6 1 1518418757 6 12-Feb-2018 06:59:17
7 1 1518418808 11 12-Feb-2018 07:00:08
我想根据start_time
中的差异对值进行分组和求和对于上述数据,总和应分三组计算:
user_id sum
1 15 + 8
1 9 + 12 + 18
1 6 + 11
因此,每组中的值有1分钟的差异。这1可以被认为是任何x分钟的差异。
我也在尝试LAG
功能,但无法完全理解它。我希望我能够解释我的问题。
答案 0 :(得分:1)
您可以使用普通group by
来实现您的目标。只需使所有start_time
值等于属于同一分钟。例如
select user_id, start_time/60, sum(inserted_value)
from log_table
group by user_id, start_time/60
我假设您的start_time
列包含表示毫秒的整数,因此/60
会将它们正确地截断为几分钟。如果值为浮点数,则应使用floor(start_time/60)
。
如果您还想选择一个人类可读的分组日期,您可以将to_timestamp((start_time/60)*60)
添加到选择列表中。
答案 1 :(得分:1)
您可以使用LAG
检查当前行是否为>比上一行多60秒,并在每次发生时设置group_changed
(虚拟列)。
在下一步中,对该列使用运行总和。这会创建一个group_number
,您可以使用它在第三步中对结果进行分组。
WITH cte1 AS (
SELECT
testdata.*,
CASE WHEN start_time - LAG(start_time, 1, start_time) OVER (PARTITION BY user_id ORDER BY start_time) > 60 THEN 1 ELSE 0 END AS group_changed
FROM testdata
), cte2 AS (
SELECT
cte1.*,
SUM(group_changed) OVER (PARTITION BY user_id ORDER BY start_time) AS group_number
FROM cte1
)
SELECT user_id, SUM(inserted_value)
FROM cte2
GROUP BY user_id, group_number