有条件的聚合行

时间:2016-04-28 20:58:14

标签: sql postgresql amazon-redshift

我有一个用户访问表,如:

SELECT * FROM visits ORDER BY start_time;

 user_id |     start_time      |      end_time
---------+---------------------+---------------------
      10 | 2016-06-01 05:45:00 | 2016-06-01 06:00:00
      10 | 2016-06-01 06:05:00 | 2016-06-01 06:30:00
      10 | 2016-06-01 06:10:00 | 2016-06-01 06:40:00
      10 | 2016-06-02 10:00:00 | 2016-06-01 10:30:00
      10 | 2016-06-03 13:00:00 | 2016-06-01 14:00:00

我希望“合并”访问重叠的行,或者彼此在10分钟之内,如下所示:

 user_id |     start_time      |      end_time
---------+---------------------+---------------------
      10 | 2016-06-01 05:45:00 | 2016-06-01 06:40:00
      10 | 2016-06-02 10:00:00 | 2016-06-01 10:30:00
      10 | 2016-06-03 13:00:00 | 2016-06-01 14:00:00
  • 前三行合并为1,因为前两行彼此相距5分钟(不到10分钟),第三行与第二行重叠
  • 最后三行没有变化,因为没有行在10分钟内

我不认为使用GROUP BY是可行的,因为每行的分组函数返回值取决于多行。我认为窗口函数可以提供帮助,但一直在努力构建查询。

我正在使用AWS Redshift

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您可以使用窗口/分析功能。我认为此版本适用于您的数据:

select user_id, min(start_time) as start_time, max(end_time) as end_time
from (select t.*,
             sum(case when start_time > prev_end_time + interval '10' minute
                      then 1 else 0
                 end) over (partition by user_id order by start_time) as grp
      from (select t.*,
                   lag(end_time) over (partition by user_id order by start_time) as prev_end_time
            from t
           ) t
     ) t
group by grp, user_id;

此方法不适用于所有数据。特别是,它假定用户没有重复的开始时间。它也可以通过复杂的多重叠来获得时髦。但是,在许多情况下,这种逻辑确实有效。