现在的位置: 首页 > 综合 > 正文

Oracle:Rank,Dense_Rank,Row_Number比较

2014年01月18日 ⁄ 综合 ⁄ 共 1383字 ⁄ 字号 评论关闭

正常情况下rank等这三个分析函数的使用是可以替代,但真正碰到特别需求的时候,就需要注意他们的区别了。

文章出自:http://trailblizer.blog.163.com/blog/static/59630364200982792143361/

一个员工信息表

Create Table EmployeeInfo (CODE Number(3) Not Null,EmployeeName varchar2(15),DepartmentID Number(3),Salary NUMBER(7,2),

Constraint PK_EmployeeInfo Primary Key (CODE));

Select * From EMPLOYEEINFO

现执行SQL语句:

Select EMPLOYEENAME,SALARY, 

RANK() OVER (Order By SALARY Desc)  "RANK",

DENSE_RANK() OVER (Order By SALARY Desc ) "DENSE_RANK",

ROW_NUMBER() OVER(Order By SALARY Desc) "ROW_NUMBER"

 From EMPLOYEEINFO

结果如下:

Rank,Dense_rank,Row_number函数为每条记录产生一个从1开始至N的自然数,N的值可能小于等于记录的总数。这3个函数的唯一区别在于当碰到相同数据时的排名策略。

①ROW_NUMBER:

Row_number函数返回一个唯一的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增。

②DENSE_RANK:

Dense_rank函数返回一个唯一的值,除非当碰到相同数据时,此时所有相同数据的排名都是一样的。

③RANK:

Rank函数返回一个唯一的值,除非遇到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名。

同时也可以分组排序,也就是在Over从句内加入Partition by groupField:

 

Select DEPARTMENTID,EMPLOYEENAME,SALARY, 

RANK() OVER ( Partition By DEPARTMENTID Order By SALARY Desc) "RANK",

DENSE_RANK() OVER ( Partition By DEPARTMENTID Order By SALARY Desc ) "DENSE_RANK",

ROW_NUMBER() OVER( Partition By DEPARTMENTID Order By SALARY Desc) "ROW_NUMBER"

From EMPLOYEEINFO 

结果如下:

现在如果插入一条工资为空的记录,那么执行上述语句,结果如下:

会发现空值的竟然排在了第一位,这显然不是想要的结果。解决的办法是在Over从句Order By后加上 NULLS Last即:

Select EMPLOYEENAME,SALARY, 

RANK() OVER (Order By SALARY Desc  Nulls Last)  "RANK",

DENSE_RANK() OVER (Order By SALARY Desc Nulls Last) "DENSE_RANK",

ROW_NUMBER() OVER(Order By SALARY Desc Nulls Last ) "ROW_NUMBER"

 From EMPLOYEEINFO

结果如下:

抱歉!评论已关闭.