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
SQL中ROW_NUMBER()/RANK() /DENSE_RANK() OVER函数的基本用法的更多相关文章
- sqlserver 中row_number,rank,dense_rank,ntile排名函数的用法
1.row_number() 就是行号 2.rank:类似于row_number,不同之处在于,它会对order by 的字段进行处理,如果这个字段值相同,那么,行号保持不变 3.dense_rank ...
- SQL Server中排名函数row_number,rank,dense_rank,ntile详解
SQL Server中排名函数row_number,rank,dense_rank,ntile详解 从SQL SERVER2005开始,SQL SERVER新增了四个排名函数,分别如下:1.row_n ...
- 大数据学习day29-----spark09-------1. 练习: 统计店铺按月份的销售额和累计到该月的总销售额(SQL, DSL,RDD) 2. 分组topN的实现(row_number(), rank(), dense_rank()方法的区别)3. spark自定义函数-UDF
1. 练习 数据: (1)需求1:统计有过连续3天以上销售的店铺有哪些,并且计算出连续三天以上的销售额 第一步:将每天的金额求和(同一天可能会有多个订单) SELECT sid,dt,SUM(mone ...
- 知方可补不足~row_number,rank,dense_rank,ntile排名函数的用法
回到目录 这篇文章介绍SQL中4个很有意思的函数,我称它的行标函数,它们是row_number,rank,dense_rank和ntile,下面分别进行介绍. 一 row_number:它为数据表加一 ...
- SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()
>>>>英文版 (更简洁易懂)<<<< 转载自:https://dzone.com/articles/difference-between-rownum ...
- ROW_NUMBER()/RANK()/DENSE_RANK()/ntile() over()
ROW_NUMBER()/RANK()/DENSE_RANK()/ntile() over() 今天女票问我SqlServer的四种排序,当场写了几句Sql让她了解,现把相关Sql放上来. 首先, ...
- Hive学习之路 (十四)Hive分析窗口函数(二) NTILE,ROW_NUMBER,RANK,DENSE_RANK
概述 本文中介绍前几个序列函数,NTILE,ROW_NUMBER,RANK,DENSE_RANK,下面会一一解释各自的用途. 注意: 序列函数不支持WINDOW子句.(ROWS BETWEEN) 数据 ...
- 在MySQL中实现Rank高级排名函数【转】
MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...
- 在MySQL中实现Rank高级排名函数
MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...
随机推荐
- python-下载百度图片到本地
import requests import os def getManyPages(keyword,pages): params=[] for i in range(30,30*pages+30,3 ...
- qualcomm compile instructions
qualcomm编译指令 Compile the Entire Android Software source build/envsetup.sh lunch msm8909-userdebug ma ...
- SpringMVC系列(十四)Spring MVC的运行流程
Spring MVC的运行流程图: 1.首先看能不能发送请求到Spring MVC的DispatcherServlet的url-pattern2.如果能发送请求,就看在Spring MVC中是否存在对 ...
- Java如何使用线程解决死锁?
在Java编程中,如何使用线程解决死锁? 以下示例演示如何使用线程的概念解决死锁问题. // from W w w .Y I I b AI.c o M package com.yiibai; impo ...
- JDBC Like子句实例
在本教程将演示如何在JDBC应用程序中,从数据库表中查询数据记录, 在查询选择记录时使用Like子句添加其他条件. 在执行以下示例之前,请确保您已经准备好以下操作: 具有数据库管理员权限,以在给定模式 ...
- e812. 强制弹出菜单为重组件
By default, Swing popup menus used by JMenu and JPopupMenu are lightweight. If heavyweight component ...
- gtest日志在工程项目中的应用
网上有各种gtest的入门教学,这里就不一一重复了.本文的目的是讲解如何将gtest应用于工程应用中.利用测试驱动开发这样的理论,来先写测试代码,当自动化测试跑通以后,主工程的代码也就编写完了. 这里 ...
- Remote SSH: Using JSCH with Expect4j
Now-a-days, we can see that whole world is moving around Clouds and virtualization. More and more ap ...
- Invalid input for operation: physical_network 'physnet1' unknown for flat provider network.
在devstack中 按照这个教程给bare metal创建flat network,一切都配置好之后, 执行net-create时遇到错误: Invalid input for operation ...
- C# 获取文件夹下的所有文件的文件名
String path = @"X:\xxx\xxx"; //第一种方法 var files = Directory.GetFiles(path, "*.txt" ...