SQL如何实现动态排名统计 掌握DENSE_RANK排序逻辑

张开发
2026/4/16 20:48:15 15 分钟阅读

分享文章

SQL如何实现动态排名统计 掌握DENSE_RANK排序逻辑
DENSE_RANK() 实现“并列不跳号”排名与ROW_NUMBER()强制唯一和RANK()并列跳号本质不同必须配合OVER(ORDER BY...)使用不可与GROUP BY混用需通过CTE或子查询先聚合再排名。为什么 DENSE_RANK() 不是 ORDER BY ROW_NUMBER()因为 DENSE_RANK() 的核心是「并列不跳号」而 ROW_NUMBER() 强制唯一编号RANK() 并列但会跳号。比如分数 [100, 95, 95, 90]三者结果分别是[1,2,2,3]、[1,2,3,4]、[1,2,2,4]。实际做销售榜、年级排名时跳号RANK会让第 3 名看起来像“断层”用户困惑而 ROW_NUMBER 把并列两人硬拆成第 2 和第 3违背业务语义。实操建议DENSE_RANK() 必须配合 OVER (ORDER BY ...)不能单独用排序字段允许多列如 OVER (ORDER BY dept_id, salary DESC)先按部门再按薪资如果想按组内排名必须加 PARTITION BY否则全表统排GROUP BY 后还能用 DENSE_RANK() 吗不能直接用。一旦用了 GROUP BY非聚合字段不可引用而 DENSE_RANK() 是窗口函数依赖原始行粒度。常见错误是写成SELECT dept_id, DENSE_RANK() OVER (ORDER BY AVG(salary)) FROM emp GROUP BY dept_id;这会报错column salary must appear in the GROUP BY clause or be used in an aggregate function。根本矛盾在于窗口函数运行在「分组前」的行集上聚合后只剩一行窗口无意义。正确做法分两步先用子查询或 CTE 算出每组聚合值如 AVG(salary)保留 dept_id在外层对这个结果集用 DENSE_RANK() OVER (ORDER BY avg_salary)示例 Felvin AI无代码市场只需一个提示快速构建应用程序

更多文章