上面两篇文章介绍了一下使用spark分组求解top值的两种方式,我们在日常工作中也可能会遇到另外一种情况,即对源数据求解每个分组的前百分之多少的情况,这种情况如何解决呢,其实和分组求top的方式类似,只不过该种情况会使用另外一种窗口函数percent_rank(),下面简单说明一下:
一:java版本
1.准备原始数据
原始数据datasetMarket=spark.read.parquet("basePath").select("学校", "班级","成绩")
2.对要进行分组的数据分组进行排序,并计算各数据在自己所在组内的排名的百分比。
Column alias = functions.percent_rank()
.over(Window.partitionBy("学校", "班级")
.orderBy(desc("成绩")));
其中partitionBy()表示分组的粒度,orderby表示按照那个字段排序排名。
最后生成的alias则为要进行分组数据的一个列,其中包含数据的排名信息。
3.将第一步计算得到的排名信息添加为原始数据列中。
datasetMarket.withColumn("rowNumber", alias)
.filter(col("rowNumber").leq(0.1))
其中rowNumber为排名占比列,后面的filter表示得到的各分组的排名占比小于0.1的结果。
二:sparkSql版本
1.首先准备源数据
datasetMarket=spark.read.parquet("basePath").select("学校", "班级","成绩")
2.创建临时视图
在获取源数据之后,对数据创建临时视图,格式如下:
datasetMarket.createTempView("groupTop")
3.核心语句,分组top值
spark.sql(select "学校, 班级,成绩 from (select 学校, 班级,成绩, percent_rank()
over(partition by 学校, 班级 order by 成绩 desc) as rowNumber from groupTop) as rn where rn.rowNumber <=0.1")
上面两种方式都可以计算出每个分组的前百分之多少的结果。