PySpark与Redshift SQL中row_number的平局处理差异及疑问
平局场景下的排名逻辑解答
原始数据表
year subject marks student name 2023 Maths 91 Jon 2023 Maths 71 Dany 2023 Maths 71 Rob 2023 Maths 85 Joffery
执行的PySpark代码
.withColumn('Ranking', f.row_number().over(\ Window.partitionBy('year', 'subject').orderBy(f.col('marks').asc())))
疑问解答
1. 分数相同的Dany和Rob谁会获得Ranking=1?
没法确定。row_number()遇到分数相同的平局时,会根据底层数据的存储顺序或者执行时的分区shuffle结果分配排名,这两个因素都不受控制,所以没法提前判定Dany和Rob谁能拿到1名。
2. 多次执行结果是否会变化?
有可能变化。如果数据的存储分区变动,或者执行时shuffle过程产生不同的顺序,相同分数的两条记录排名就可能互换。只有在orderBy里添加唯一标识字段(比如student name)固定排序逻辑,多次执行的结果才会一致。
3. PySpark与Redshift SQL如何处理此类平局?
PySpark
- 使用
row_number()时,平局的排名完全依赖底层数据物理顺序或shuffle后的顺序,没有固定规则。要让排名稳定,必须在orderBy中加入唯一字段(比如学生姓名、ID)打破平局。 - 另外PySpark提供
rank()和dense_rank()函数:rank()给相同分数的记录相同排名,下一个排名会跳过对应数量的名次;dense_rank()同样给相同分数记录相同排名,但下一个排名不会跳号。
Redshift SQL
- Redshift的
ROW_NUMBER()处理平局的逻辑和PySpark一致:当排序字段无法区分记录时,会按数据的物理存储顺序(比如磁盘存储位置)分配排名,这个顺序不确定,多次执行结果可能变化。 - Redshift也支持
RANK()和DENSE_RANK()函数,行为和PySpark对应函数一致。要确保平局时排名稳定,必须在ORDER BY子句中添加唯一字段明确排序规则。
内容的提问来源于stack exchange,提问作者shubham tambere
相关产品推荐
相关产品推荐

