如何基于category的weightage总和降序实现dense_rank排名
按分类总权重降序dense_rank排名实现方案
原有写法问题
你之前的写法存在两个核心错误:
- 加了
partition by category会为每个分类单独创建排名分区,无法实现跨分类的总权重比较 - 排序依据是单条记录的
weightage字段值,不是每个分类下所有weightage的总和
正确实现代码
写法1:窗口函数嵌套(推荐,适配MySQL8.0+、Spark SQL、Hive、PostgreSQL等主流引擎)
SELECT category, weightage, As_of_date, DENSE_RANK() OVER(ORDER BY SUM(weightage) OVER(PARTITION BY category) DESC) AS dense_rank FROM 你的表名;
逻辑说明:
内层窗口函数SUM(weightage) OVER(PARTITION BY category)会先计算每个分类的权重总和,同一个分类下所有行的这个总和值完全相同;外层DENSE_RANK不设置分区,直接基于所有分类的总权重降序排名,即可实现同一个分类所有行排名一致的需求。
写法2:子查询关联(兼容更低版本SQL引擎)
如果你的运行环境不支持窗口函数嵌套,可以先预聚合计算每个分类的总权重,再关联回原表排名:
SELECT t1.category, t1.weightage, t1.As_of_date, DENSE_RANK() OVER(ORDER BY t2.total_weight DESC) AS dense_rank FROM 你的表名 t1 LEFT JOIN ( SELECT category, SUM(weightage) AS total_weight FROM 你的表名 GROUP BY category ) t2 ON t1.category = t2.category;
结果验证
各分类总权重计算:
- 678def:200+200=400 → 排名1
- 123def:50*5=250 → 排名2
- 456abc:100+100=200 → 排名3
- 123abc:50 → 排名4
和你给出的预期结果完全匹配。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

