首页 > 解决方案 > 在java中的spark数据框中选择groupBy中未包含列的对应值

问题描述

我有一个数据框如下

col1, col2, version_time, col3

root
 |-- col1: string (nullable = true)
 |-- col2: integer (nullable = true)
 |-- version_time: timestamp (nullable = true) 
 |-- col3: string (nullable = true)

下面是一些示例行

col1  col2  timestamp                 col3
 1     A    2021-05-09T13:53:20.219Z   B
 2     A    2021-01-09T13:53:20.219Z   C
 3     A    2021-02-09T13:53:20.219Z   D
 1     A    2020-05-09T13:53:20.219Z   E
 1     A    2019-05-09T13:53:20.219Z   F

我想要的是 groupBy col1 和 col2 在 max(timestamp) 上聚合并返回所有列。

col1  col2  timestamp                 col3
 1     A    2021-05-09T13:53:20.219Z   B
 2     A    2021-01-09T13:53:20.219Z   C
 3     A    2021-02-09T13:53:20.219Z   D

如果我在数据帧上使用 groupBy ,它将下降col3。我必须加入原始数据框才能获得 col3 的值

    col1  col2  timestamp                 
     1     A    2021-05-09T13:53:20.219Z
     2     A    2021-01-09T13:53:20.219Z
     3     A    2021-02-09T13:53:20.219Z

如果我使用 Window.partitionBy,我仍然会有 5 行具有相同时间戳值的 col1 和 col2,这不是我想要的。

col1  col2  timestamp                 col3
 1     A    2021-05-09T13:53:20.219Z   B
 2     A    2021-01-09T13:53:20.219Z   C
 3     A    2021-02-09T13:53:20.219Z   D
 1     A    2021-05-09T13:53:20.219Z   E
 1     A    2021-05-09T13:53:20.219Z   F

还有其他选择吗?

标签: dataframeapache-sparkapache-spark-sqlspark-java

解决方案


您可以在 col1 和 col2 上使用 rank 窗口函数分区并根据时间戳对其进行排序,然后选择 rank=1 的记录。Spark sql 等价物将是这样的。

select * from (select col1,col2,rank() over(partition by col1,col2 order by timestamp desc) as rnk)temp where rnk=1

推荐阅读