有条件地聚合行

Conditionally Aggregate Rows

我有一个 table 的用户访问是这样的:

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

我想要 "merge" 访问重叠的行,或者彼此相隔 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

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

我正在使用 AWS Redshift

感谢您的帮助!

您可以为此使用 window/analytic 函数。我认为此版本适用于您的数据:

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;

此方法不适用于所有数据。特别是,它假定用户没有重复的开始时间。它也可能因复杂的多重重叠而变得时髦。但是,在很多情况下,这个逻辑确实有效。