有条件地聚合行
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
- 前 3 行合并为 1,因为前两行彼此相隔不到 5 分钟(不到 10 分钟),第三行与第二行重叠
- 最后三行没有变化,因为在它们之后的 10 分钟内没有任何行
我认为使用 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;
此方法不适用于所有数据。特别是,它假定用户没有重复的开始时间。它也可能因复杂的多重重叠而变得时髦。但是,在很多情况下,这个逻辑确实有效。
我有一个 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
- 前 3 行合并为 1,因为前两行彼此相隔不到 5 分钟(不到 10 分钟),第三行与第二行重叠
- 最后三行没有变化,因为在它们之后的 10 分钟内没有任何行
我认为使用 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;
此方法不适用于所有数据。特别是,它假定用户没有重复的开始时间。它也可能因复杂的多重重叠而变得时髦。但是,在很多情况下,这个逻辑确实有效。