基于Spark SQL/PySpark从时间戳范围获取唯一最大值
解决方案:Spark SQL实现分组取唯一最大值行
首先,你的原查询存在逻辑问题:GROUP BY子句中包含了index、score、date这些你要取最大值的字段,这会导致每个唯一的(index, score, date, col3, col4)组合都成为独立分组,max(index)实际上就是分组本身的index,完全无法实现聚合去重的效果,而且DISTINCT在这里是多余的。
针对你的需求,以下是两种常见场景的等效实现方法:
场景1:按维度分组,获取每组中时间戳(date)最大的完整行
如果你的目标是按col2、col3、col4分组,保留每组中date最大的那一行的所有字段,可以使用窗口函数ROW_NUMBER()实现:
SELECT index, score, col2, col3, col4, date FROM ( SELECT index, score, col2, col3, col4, make_timestamp(last_day(col5)) AS date, -- 按col2、col3、col4分区,按date降序排序,给每行打排名 ROW_NUMBER() OVER (PARTITION BY col2, col3, col4 ORDER BY make_timestamp(last_day(col5)) DESC) AS rn FROM table ) t -- 只保留每组中排名第一的行(即date最大的行) WHERE rn = 1
如果组内存在多个date相同的最大值行,想要保留所有这些行,可以把ROW_NUMBER()换成RANK()。
场景2:按维度分组,聚合获取每组的index、score、date最大值
如果你的目标是按col2、col3、col4分组,返回每组的最大index、最大score、最大date,只需修正GROUP BY子句,只按非聚合字段分组:
SELECT MAX(index) AS index, MAX(score) AS score, col2, col3, col4, MAX(make_timestamp(last_day(col5))) AS date FROM table -- 仅按需要分组的维度列分组,不要包含聚合字段 GROUP BY col2, col3, col4
关键说明
- Spark SQL中没有
MAXDistinct()函数,但通过窗口函数或正确的GROUP BY分组逻辑,完全可以实现你要的去重+取最大值需求。 - 窗口函数适合需要保留完整行数据的场景,GROUP BY聚合适合只需要最大值聚合结果的场景。
内容的提问来源于stack exchange,提问作者Wendy Velasquez
相关产品推荐
相关产品推荐

