浅谈Oracle中的row_number()、rank()、dense_rank()

浅谈Oracle中的row_number()、rank()、dense_rank()
最新回答
大神说不管屌丝多帅都滚开

2023-02-10 11:31:41

Oracle中的row_number()、rank()、dense_rank()均为排名分析函数,需配合OVER()子句使用,核心区别在于序号生成规则与重复值处理方式

1. ROW_NUMBER()
为每行分配唯一连续序号,即使排序字段值相同,序号也不重复。例如,按成绩降序排列时,即使两人并列第一,仍会分别标记为1和2。其语法为ROW_NUMBER() OVER(ORDER BY 列名),必须包含ORDER BY子句以确定排序逻辑。该函数适用于需要严格区分行顺序的场景,如分页查询或唯一标识行。

2. RANK()
根据排序字段值生成排名,相同值共享同一排名,后续排名跳过重复数量。例如,两人并列第一后,下一名直接为第三名(跳过第二)。语法为RANK() OVER(ORDER BY 列名),同样依赖ORDER BY。此函数适用于允许排名间断的场景,如竞赛成绩排名,但需注意NULL值默认排在最前(可通过NULLS LAST调整)。

3. DENSE_RANK()
与RANK()类似,但排名连续不间断。相同值共享排名后,下一名紧接上一排名值。例如,两人并列第一后,下一名仍为第二名。语法为DENSE_RANK() OVER(ORDER BY 列名)。该函数适用于需要连续排名的场景,如等级划分或阶梯式奖励分配。

关键注意事项

  • 分区功能:三者均可通过PARTITION BY子句实现分组内排名。例如,PARTITION BY department ORDER BY salary DESC会按部门分组,并在组内按薪资降序排名。
  • 空值处理:RANK()和DENSE_RANK()默认将NULL视为最大值,可通过NULLS LAST将其排至末尾。
  • 性能影响:分析函数需扫描全表或分区,大数据量时可能影响性能,建议结合索引优化。

总结

  • 需唯一序号时选ROW_NUMBER();
  • 允许排名间断用RANK();
  • 要求排名连续用DENSE_RANK()。
    三者均需OVER(ORDER BY...)子句,且分组内排名从1开始。正确使用可简化复杂排序逻辑,提升查询可读性。