我想对放置在Redshift中的数据集应用自定义逻辑。 输入数据示例:
userid, event, fileid, timestamp, ....
100000, start, 120, 2018-09-17 19:11:40
100000, done, 120, 2018-09-17 19:12:40
100000, done, 120, 2018-09-17 19:13:40
100000, start, 500, 2018-09-17 19:13:50
100000, done, 120, 2018-09-17 19:14:40
100000, done, 500, 2018-09-17 19:14:50
100000, done, 120, 2018-09-17 19:15:40
这意味着:
file 120: start-----done-----done-----done-----done
file 150: start-----done
time : 11:40----12:40----13:40-----14:40-----15:40
但是应该看起来像
file 120: start-----done-----done
file 150: start-----done
time : 11:40----12:40----13:40-----14:40-----15:40
文件150一旦启动,文件120已被中断
请记住,如果此处有不同的用户和许多不同的文件,那么很多。
清洗后的数据应为:
userid, event, fileid, timestamp, ....
100000, start, 120, 2018-09-17 19:11:40
100000, done, 120, 2018-09-17 19:12:40
100000, done, 120, 2018-09-17 19:13:40
100000, start, 500, 2018-09-17 19:13:50
100000, done, 500, 2018-09-17 19:14:50
同一用户不能一次拥有多个并发文件。因此,第二个事件开始后,第一个事件不会从当前数据集中删除。
代码很简单,但是在python上,例如,对于Google Dataflow来说,它很容易扩展,但是将100GB以上的数据从AWS迁移到GC并不是一个好主意。
问题1: 是否可以在SQL上做到这一点(使用postgres / redshift特定功能),或者更好地使用Spark? (但不确定如何在那里实现)
问题2: 关于使用AWS Batch或其他任何可能导致apache Beam的建议,这很容易,而且很明显,但是AWS Batch的工作方式以及如何将数据集按块划分(如每个用户分组)是一个很大的问题。 我的建议是以某种方式将数据从redshift卸载到S3存储桶中,然后以单独的file = user方式将其划分,然后,如果aws批处理支持此功能-只需输入存储桶,每个文件应在已创建的实例上同时处理。不知道这是否有意义。
答案 0 :(得分:1)
如果您要删除fileid
与用户最近的start
不匹配的行,可以使用lag(ignore nulls)
:
select t.*
from (select t.*,
lag(case when event = 'start' then file_id end ignore nulls) over (partition by userid order by timestamp) as start_fileid
from t
) t
where event = 'start' or start_fileid = fileid;