通过列值的差异在SQL中对数据进行分组

时间:2018-02-12 06:34:33

标签: sql postgresql datetime group-by analytic-functions

我在postgres表的日志表中有以下数据:

  1. logid => int(自动增量)
  2. start_time => bigint(存储时代价值)
  3. inserted_value => INT
  4. 以下是存储在表格中的数据(其中实际开始时间不是列,只是以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功能,但无法完全理解它。我希望我能够解释我的问题。

2 个答案:

答案 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

SQL Fiddle