使用 Apache Spark 对结果进行子分组 SQL

Sub Grouping the results using Apache Spark SQL

我有以下事件 table,我想按照下面指定的更小的时间段对它们进行分组。

table 必须分成较小的集合,其中集合的开始和结束行由 geohash 确定,如果 geohash 相同,则设置继续包含这些行,直到它发现下一个 geohash 不同。

key time_stamp  geohash
k1  1           abcdfg
k1  5           abcdfg
k1  7           abcdf1
k1  9           abcdfg
k1  10          abcdf2
k1  12          abcdf2
k1  21          abcdf2

如何使用 Apache Spark SQL 语法生成以下输出

key geohash first_time  last_time   duration    num_events
k1  abcdfg  1           5           4           2
k1  abcdf1  7           7           0           1
k1  abcdfg  9           9           0           1
k1  abcdf2  10          21          11          3

谁能帮我实现这个目标。

这是一种空岛问题。这是使用 row_number() 和聚合解决它的一种方法:

select
    key, 
    geohash, 
    min(timestamp) first_time,
    max(timestamp) last_time,
    max(timestamp) - min(timestamp) duration,
    count(*) num_events
from (
    select
        t.*,
        row_number() over(partition by key order by timestamp) rn1,
        row_number() over(partition by key, geohash order by timestamp) rn2
    from mytable t
) t
group by 
    key,
    geohash,
    rn1 - rn2

并且,只是为了好玩:您也可以使用条件 window 总和来做到这一点:

select
    key, 
    geohash, 
    min(timestamp) first_time,
    max(timestamp) last_time,
    max(timestamp) - min(timestamp) duration,
    count(*) num_events
from (
    select
        t.*,
        sum(case when lag_geohash = geohash then 0 else 1 end) 
            over(partition by key order by timestamp) grp
    from (
        select
            t.*,
            lag(geohash) over(partition by key order by timestamp) lag_geohash
        from mytable t
    ) t 
) t
group by 
    key,
    geohash,
    grp