SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

时间:2021-09-16 03:08:45

>>>>英文版 (更简洁易懂)<<<<

转载自:https://dzone.com/articles/difference-between-rownumber

One of the most obvious and useful set of window functions are ranking functions where rows from your result set are ranked according to a certain scheme. There are three ranking functions:

  • ROW_NUMBER()
  • RANK()
  • DENSE_RANK()

The difference is easy to remember. For the examples, let’s assume we have this table (using PostgreSQL syntax):

CREATE TABLE t(v) AS
SELECT * FROM (
VALUES('a'),('a'),('a'),('b'),
('c'),('c'),('d'),('e')
) t(v)

ROW_NUMBER()

… assigns unique numbers to each row within the PARTITION given the ORDER BY clause. So you’d get:

SELECT v, ROW_NUMBER() OVER()
FROM t

Note that some SQL dialects (e.g. SQL Server) require an explicit ORDER BY clause in the OVER() clause:

SELECT v, ROW_NUMBER() OVER(ORDER BY v)
FROM t

The above query returns:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

RANK()

… behaves like ROW_NUMBER(), except that “equal” rows are ranked the same. If we substitute RANK() into our previous query:

SELECT v, RANK() OVER(ORDER BY v)
FROM t

… then the result we’re getting is this:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

As you can see, much like in a sports ranking, we have gaps between the different ranks. We can avoid those gaps by using

DENSE_RANK()

Trivially, DENSE_RANK() is a rank with no gaps, i.e. it is “dense”. We can write:

SELECT v, DENSE_RANK() OVER(ORDER BY v)
FROM t

… to obtain

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

One interesting aspect of DENSE_RANK() is the fact that it “behaves like” ROW_NUMBER()when we add the DISTINCT keyword.

SELECT DISTINCT v, DENSE_RANK() OVER(ORDER BY v)
FROM t

… to obtain

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

In fact, ROW_NUMBER() prevents you from using DISTINCT, because ROW_NUMBER()generates unique values across the partition beforeDISTINCT is applied:

SELECT DISTINCT v, ROW_NUMBER() OVER(ORDER BY v)
FROM t
ORDER BY 1, 2

DISTINCT has no effect:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

Putting it all together

A good way to understand the three ranking functions is to see them all in action side-by-side. Run this query

SELECT
v,
ROW_NUMBER() OVER(ORDER BY v),
RANK() OVER(ORDER BY v),
DENSE_RANK() OVER(ORDER BY v)
FROM t
ORDER BY 1, 2

… to obtain:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

Note that unfortunately, the WINDOW clause is not supported in all databases.

>>>>中文版<<<<

转载自:https://www.cnblogs.com/SunnyZhu/p/5762898.html

SqlServer的四种排序,当场写了几句Sql让她了解,现把相关Sql放上来。

首先,我们创建一些测试数据。

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()
if OBJECT_ID('Tempdb.dbo.#Tmp') is not null
drop table #Tmp
create table #Tmp
(
name nvarchar(10)
) insert into #Tmp
select N'张三'
union
select N'李四'
union
select N'王五'
union
select N'赵六'
union
select N'朱七'
union
select N'王八'
union all
select N'张三'
SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

最后一个union用union all,因为我们多一行"张三"。

一、ROW_NUMBER() over(partition by columnname order by columnname)

select ROW_NUMBER()over(order by name) as num,* from #Tmp

可以得到按name排序的结果集。

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

ROW_NUMBER() over()还有一种用法,可以针对某列进行分组排序。

下面结果可以看到张三有1和2两个排序,而其他的名字排序都只有1。

select ROW_NUMBER()over(partition by name order by name) as num,* from #Tmp

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

二、RANK()over(order by columnname)

大家可以从下面的结果集看到,结果集少了5的编号,而有两个4的编号,然后直接跳到编号6。

select RANK()over(order by name),* from #Tmp

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

三、DENSE_RANK()over(order by columnname)

select DENSE_RANK()over(order by name),* from #Tmp

执行Sql后发现,下面的结果集有2个编号4的行,紧接着就是编号5的行。

DENSE_RANK()函数和RANK()函数差不多。

RANK()函数不管分几组,最后的编号一定和行数相同。

DENSE_RANK()函数最后的编号和分组的数目有关。

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

四、NTILE()OVER(ORDER BY COLUMNNAME)

select NTILE(2)over(order by name),* from #Tmp
select NTILE(3)over(order by name),* from #Tmp
NTILE后面的数字,是要把查询得到的结果平均分为几组。
如下图分为2和3组。
如果行数平均划分后还有余行,那么就把行分在最前面的几组上。
比如我们的结果有7行,要分为3组。
那么第一组3行,第二组2行,第三组2行。
如果我们结果有14行,平均分为3组。
那么第一组5行,第二组5行,第三组4行。
依此类推。

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

One of the most obvious and useful set of window functions are ranking functions where rows from your result set are ranked according to a certain scheme. There are three ranking functions:

  • ROW_NUMBER()
  • RANK()
  • DENSE_RANK()

The difference is easy to remember. For the examples, let’s assume we have this table (using PostgreSQL syntax):

 
CREATE TABLE t(v) AS
 
SELECT * FROM (
 
  VALUES('a'),('a'),('a'),('b'),
 
        ('c'),('c'),('d'),('e')
 
) t(v)
 

ROW_NUMBER()

… assigns unique numbers to each row within the PARTITION given the ORDER BY clause. So you’d get:

 
SELECT v, ROW_NUMBER() OVER()
 
FROM t
 

Note that some SQL dialects (e.g. SQL Server) require an explicit ORDER BY clause in the OVER() clause:

 
SELECT v, ROW_NUMBER() OVER(ORDER BY v)
 
FROM t
 

The above query returns:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

(see also this SQLFiddle)

RANK()

… behaves like ROW_NUMBER(), except that “equal” rows are ranked the same. If we substitute RANK() into our previous query:

 
SELECT v, RANK() OVER(ORDER BY v)
 
FROM t
 

… then the result we’re getting is this:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

(see also this SQLFiddle)

As you can see, much like in a sports ranking, we have gaps between the different ranks. We can avoid those gaps by using

DENSE_RANK()

Trivially, DENSE_RANK() is a rank with no gaps, i.e. it is “dense”. We can write:

 
SELECT v, DENSE_RANK() OVER(ORDER BY v)
 
FROM t
 

… to obtain

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

(see also this SQLFiddle)

One interesting aspect of DENSE_RANK() is the fact that it “behaves like” ROW_NUMBER()when we add the DISTINCT keyword.

 
SELECT DISTINCT v, DENSE_RANK() OVER(ORDER BY v)
 
FROM t
 

… to obtain

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

(see also this SQLFiddle)

In fact, ROW_NUMBER() prevents you from using DISTINCT, because ROW_NUMBER()generates unique values across the partition beforeDISTINCT is applied:

 
SELECT DISTINCT v, ROW_NUMBER() OVER(ORDER BY v)
 
FROM t
 
ORDER BY 1, 2
 

DISTINCT has no effect:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

(see also this SQLFiddle)

Putting it all together

A good way to understand the three ranking functions is to see them all in action side-by-side. Run this query

 
SELECT
 
  v,
 
  ROW_NUMBER() OVER(ORDER BY v),
 
  RANK()       OVER(ORDER BY v),
 
  DENSE_RANK() OVER(ORDER BY v)
 
FROM t
 
ORDER BY 1, 2
 

… or this one (using the SQL standard WINDOW clause, to reuse window specifications):

 
SELECT
 
  v,
 
  ROW_NUMBER() OVER(w),
 
  RANK()       OVER(w),
 
  DENSE_RANK() OVER(w)
 
FROM t
 
WINDOW w AS (ORDER BY v)
 

… to obtain:

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()

(see also this SQLFiddle)

Note that unfortunately, the WINDOW clause is not supported in all databases.

SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()的更多相关文章

  1. SQL Server中排名函数row&lowbar;number&comma;rank&comma;dense&lowbar;rank&comma;ntile详解

    SQL Server中排名函数row_number,rank,dense_rank,ntile详解 从SQL SERVER2005开始,SQL SERVER新增了四个排名函数,分别如下:1.row_n ...

  2. SQL Server:排名函数row&lowbar;number&comma;rank&comma;dense&lowbar;rank&comma;ntile详解

    1.Row_Number函数 row_number函数大家比较熟悉一些,因为它的用途非常的广泛,我们经常在分页与排序中用到它,它的功能就是在每一行中生成一个连续的不重复的序号 例如: select S ...

  3. ROW&lowbar;NUMBER&lpar;&rpar;&sol;RANK&lpar;&rpar;&sol;DENSE&lowbar;RANK&lpar;&rpar;&sol;ntile&lpar;&rpar; over&lpar;&rpar;

    ROW_NUMBER()/RANK()/DENSE_RANK()/ntile() over()   今天女票问我SqlServer的四种排序,当场写了几句Sql让她了解,现把相关Sql放上来. 首先, ...

  4. 【SQL】四种排序开窗函数

    一 .简单了解什么是开窗函数 什么是开窗函数,开窗函数有什么作用,特征是什么? 所谓开窗函数就是定义一个行为列,简单讲,就是在你查询的结果上,直接多出一列值(可以是聚合值或是排序号),特征就是带有ov ...

  5. 知方可补不足~row&lowbar;number&comma;rank&comma;dense&lowbar;rank&comma;ntile排名函数的用法

    回到目录 这篇文章介绍SQL中4个很有意思的函数,我称它的行标函数,它们是row_number,rank,dense_rank和ntile,下面分别进行介绍. 一 row_number:它为数据表加一 ...

  6. SQL-OVER与四种排名函数:ROW&lowbar;NUMBER&lpar;&rpar;&comma;RANK&lpar;&rpar;&comma;DENSE&lowbar;RANK&lpar;&rpar;&comma;NTILE&lpar;&rpar;

    1 SELECT orderid,custid,val, ROW_NUMBER() OVER(ORDER BY val) AS rownum, RANK() OVER(ORDER BY val) AS ...

  7. SqlServer四种排序:ROW&lowbar;NUMBER&lpar;&rpar;&sol;RANK&lpar;&rpar;&sol;DENSE&lowbar;RANK&lpar;&rpar;&sol;ntile&lpar;&rpar; over&lpar;&rpar;

    首先,我们创建一些测试数据. if OBJECT_ID('Tempdb.dbo.#Tmp') is not null drop table #Tmp create table #Tmp ( name ...

  8. PCB MS SQL 排序应用&lpar;row&lowbar;number rank dense&lowbar;rank NTILE PARTITION&rpar;

    一.排序前,准备数据 --表变量 ),流程数 int) insert into @table union all union all union all union all --查看一下 select ...

  9. sqlserver 中row&lowbar;number&comma;rank&comma;dense&lowbar;rank&comma;ntile排名函数的用法

    1.row_number() 就是行号 2.rank:类似于row_number,不同之处在于,它会对order by 的字段进行处理,如果这个字段值相同,那么,行号保持不变 3.dense_rank ...

随机推荐

  1. 使用Spark分析拉勾网招聘信息&lpar;四&rpar;&colon; 几个常用的脚本与图片分析结果

    概述 前一篇文章,已经介绍了BMR的基础用法,再结合Spark和Scala的文档,我想应该是可以开始你的数据分析之路的.这一篇文章,着重进行一些简单的思路上的引导和分析.如果你分析招聘数据时,卡在了某 ...

  2. Nginx--Windows环境下Nginx&plus;tomcat配置(包括动静分离)

    前提条件: (1)已安装好tomcat,且能成功启动 (2)已安装好Nginx,且能成功启动 接下来进行配置: (1)在Nginx的conf文件夹中新增两个文件,分别如下:(新建文件后,直接复制代码即 ...

  3. android 客户端支付宝 php服务器端编写

    生成私钥 输入“genrsa -out rsa_private_key.pem 1024”命令,回车后,在当前 bin 文件目 录中会新增一个 rsa_private_key.pem 文件,其文件为原 ...

  4. rsync - 远程同步工具

    一直没有对这个命令太有深入的理解 简介 rsync 即 remote sync,一个远程与本地文件同步工具.rsync 使用的算法能够最小化所需复制的数据,因为它只移动那些修改了的文件. rsync ...

  5. R语言学习——图形初阶之散点图

    使用R内置的数据框mtcars,绘制车身重量与每加仑汽油行驶的英里数的散点图,要求横轴为车身重量(wt),纵轴为每加仑汽油行驶的英里数(mpg),并添加最优拟合曲线.标题,输出为pdf文件.代码实现如 ...

  6. ERP新人防坑指南

    本文作为初入ERP行业的新人的防坑指南,讲解了一些常见犯的错,这样也少走一些弯路,如果你是老鸟,请绕过 :-) 本文关联的代码使用kotlin编写,请自行转换为c#.java等你熟悉的语言,表述的坑在 ...

  7. 设置vim支持gbk

    linux下的默认字符集是utf-8,但Windows下默认是GBK,如果我们在linux下打开Windows中的文件就很容乱码,可以通过下面的设置使vim支持GBK编码. 首先,确认你的系统中安装了 ...

  8. Gibbs采样

    (学习这部分内容大约需要50分钟) 摘要 Gibbs采样是一种马尔科夫连蒙特卡洛(Markov Chain Monte Carlo, MCMC)算法, 其中每个随机变量从给定剩余变量的条件分布迭代地重 ...

  9. 解题:NOI 2016 优秀的拆分

    题面 其实题目不算很难,但是我调试的时候被玄学了,for循环里不写空格会RE,写了才能过.神**调了一个多小时是这么个不知道是什么的玩意(真事,可以问i207M=.=),心态爆炸 发现我们只要找AA或 ...

  10. Python学习(四)数据结构 —— set frozenset

    集合类型 set  frozenset 赋值及去重 set 是一个无序不重复元素集,还有个frozenset 类型(顾明思议,就是不可改变元素的集合): 基本功能包括关系测试和消除重复元素:set支持 ...