SQL中ROW_NUMBER()/RANK() /DENSE_RANK() OVER函数的基本用法

一、ROW_NUMBER()的用法

 

语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)

row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY colum DESC) 是先把colum列降序,再为降序以后的每条colum记录返回一个序号。
示例: 

Row_Num    colum

     1              2200

     2              2150

     3             1780

     4             1125

Row_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的,没有重复值)

实例1:

初始化数据

create table employer (employerid int ,deptid int ,salary decimal(8,1))

insert into employer values(1,1,15000.0)

insert into employer values(2,1,10000.0)

insert into employer values(3,2,19000.0)

insert into employer values(4,2,21000.0)

insert into employer values(5,3,14500.0)

insert into employer values(6,3,10000.0)

insert into employer values(7,3,44500.0)

insert into employer values(8,4,22500.0)

insert into employer values(9,4,35500.0)

insert into employer values(10,4,35500.0)

insert into employer values(11,4,36000.0)

insert into employer values(12,4,36000.0)

 

数据显示为

employerid       deptid      salary
----------- ----------- ---------------------------------------
1                         1          15000.0

2                         1          10000.0

3                         2          19000.0

4                         2          21000.0

5                         3          14500.0

6                         3          10000.0

7                         3          44500.0

8                         4          22500.0

9                         4          35500.0

10                       4          35500.0

11                       4          36000.0

12                       4          36000.0

需求:根据部门分组,显示每个部门的工资等级

预期结果:

employerid       deptid      salary              Leve 
----------- ----------- ---------------------------------------
1                         1          15000.0               1

2                         1          10000.0               2

4                         2          21000.0               1 

3                         2          19000.0               2

7                         3          44500.0               1

5                         3          14500.0               2

6                         3          10000.0               3

11                       4          36000.0               1

12                       4          36000.0               2

9                         4          35500.0               3

10                       4          35500.0               4

8                         4          22500.0               5

SQL脚本:

SELECT *, ROW_NUMBER() OVER (PARTITION BY deptid ORDER BY salary desc) Leve FROM employeer

 

实例2:

初始化数据

create table tb_EmployerSign (SignId int ,EmployerId int ,SignDate datetime)-- 创建员工签到表

insert into tb_EmployerSign values(1,1,'2014-09-15 18:21:38.130' )

insert into tb_EmployerSign values(2,2,'2014-09-16 18:21:38.130' )

insert into tb_EmployerSign values(3,3,'2014-09-14 18:21:38.130' )

insert into tb_EmployerSign values(4,4,'2014-09-16 18:21:38.130' )

insert into tb_EmployerSign values(5,1,'2014-09-17 18:21:38.130' )

insert into tb_EmployerSign values(6,2,'2014-09-17 19:21:38.130' )

insert into tb_EmployerSign values(7,3,'2014-09-19 18:21:38.130' )

insert into tb_EmployerSign values(8,4,'2014-09-20 18:21:38.130' )

数据显示为

SignId       EmployerId              SignDate
----------- ----------- -------------------------------------------
1                      1            2014-09-15 18:21:38.130

2                      2            2014-09-16 18:21:38.130

3                      3            2014-09-14 18:21:38.130

4                      4            2014-09-16 18:21:38.130

5                      1            2014-09-17 18:21:38.130

6                      2            2014-09-17 19:21:38.130

7                      3            2014-09-19 18:21:38.130

8                      4            2014-09-20 18:21:38.130

需求:查询三天内没有签到的员工最后一次签到的信息

假如今天是2014-09-21 则预期结果:

    SignId             EmployerId             SignDate                        OutDateNumb
-------------------------------------------------------------------------------------------------------
       5                           1          2014-09-17 18:21:38.130                   4

       6                           2          2014-09-17 19:21:38.130                   4

SQL脚本:

select SignId,EmployerId,SignDate,datediff(dd,SignDate,getdate()) as OutDateNumb 

from (select *,ROW_NUMBER() over(PARTITION by EmployerId order by signId DESC) numb from EmployerSign) tb 

where tb.numb=1 and datediff(dd,SignDate,getdate())>3<span style="font-size:14px;"><strong>
</strong></span>


 二、RANK()的用法

 

语法:RANK() OVER (PARTITION BY COL1 ORDER BY COL2) 

RANK()的用法和ROW_NUMBER()类似,只不过RANK()是跳跃排序,有两个第三名时接下来就是第五名(同样是在各个分组内).

例如执行如下SQL语句之后实例1中的数据显示结果如下:

SELECT *, RANK() OVER (PARTITION BY deptid ORDER BY salary desc) Leve FROM employer


结果:

employerid       deptid      salary              Leve 
----------- ----------- ---------------------------------------
1                         1          15000.0               1

2                         1          10000.0               2

4                         2          21000.0               1

3                         2          19000.0               2

7                         3          44500.0               1

5                         3          14500.0               2

6                         3          10000.0               3

11                       4          36000.0               1

12                       4          36000.0               1

9                         4          35500.0               3

10                       4          35500.0               3

8                         4          22500.0               5

 

三、DENSE_RANK()的用法

 

语法:DENSE_RANK() OVER(PARTITION BY COL1 ORDER BY COL2)

DENSE_RANK()的用法和ROW_NUMBER()类似,只不过DENSE_RANK()是连续排序,有两个第二名时仍然跟着第三名(同样在各个分组内)。

例如执行如下SQL语句后实例1中的数据显示如下:

SELECT *, DENSE_RANK() OVER (PARTITION BY deptid ORDER BY salary desc) Leve FROM employee

结果:

employerid       deptid      salary              Leve 
----------- ----------- ---------------------------------------
1                         1          15000.0               1

2                         1          10000.0               2

4                         2          21000.0               1

3                         2          19000.0               2

7                         3          44500.0               1

5                         3          14500.0               2

6                         3          10000.0               3

11                       4          36000.0               1

12                       4          36000.0               1

9                         4          35500.0               2

10                       4          35500.0               2

8                         4          22500.0               3

 

 

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值