四、            Ranking

排序与排名是我们最为常用的统计方式,比如对班级的学生根据成员进行排名,或者按照成绩高低把学生划分成若干梯队:比如最好成绩的10名学生属于第一梯队,后10名又划分为第二梯队,以此类推。Ranking设计的Key Words包括:ROW_NUMBER(),RANK(),DENSE_RANK(),NTILE()我们现在就来介绍一下他们的用法和相互之间的差异。

1.          1. ROW_NUMBER()

看到ROW_NUMBER(),我想绝大多数人会像想到Oracle的ROWNUM。他们的作用相似,都是表示某条记录所处的Index。ROW_NUMBER()比Oracle的ROWNUM更加强大的是,它可以通过OVER语句指定一个进行排序的Column,比如:ROW_NUMBER() OVER (ORDER BY CustomerID)。

我们来看一个例子:对Sales.SalesOrderHeader按照CustomerID进行排序,并显示每条记录的Row Number。

SELECT SalesOrderID,CustomerID,ROW_NUMBER() OVER (ORDER BY CustomerID) AS RowNum
FROM Sales.SalesOrderHeader

下面是查询结果:

我们发现最终的结果按照CutomerID进行排序,RowNum从1开始以此递增,每条记录(不管是否具有相同的CustomerID)拥有不同的RowNum。

提到排序,我们就不得不提到Order BY,如果我们在后面加上ORDER BY,并指定不同的排序字段,会出现怎样的结果呢?

SELECT SalesOrderID,CustomerID,ROW_NUMBER() OVER (ORDER BY CustomerID) AS RowNum
FROM Sales.SalesOrderHeader
ORDER BY SalesOrderID

查询获得的结果是:

从上图中可以看到,最终的结果以ORDER BY中指定的SalesOrderID进行排序,但是ROW_NUMBER()体现的值却是基于CustmerID排序的。

由于ROW_NUMBER()体现是基于某个确定的字段进行排序后某个DataRow所处的位置,所以它不能直接使用到Aggregate的Column中。比如下面的SQL是不合法的:

SELECT CustomerID,COUNT(*) AS OrderCount,ROW_NUMBER() OVER (ORDER BY OrderCount)
FROM Sales.SalesOrderHeader
GROUP BY CustomerID

要是想按照OrderCount,可以使用第一部分介绍的CTE:

WITH CTE_Order(CustomerID,OrderCount)
AS
(
SELECT CustomerID,COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY CustomerID
)

SELECT CustomerID,OrderCount,ROW_NUMBER() OVER (ORDER BY OrderCount)
FROM CTE_Order

2.          RANK()

RANK()的使用和ROW_NUMBER()类似。不过它与ROW_NUMBER()所不同的是:对于被指定为排序的字段,具有相同值得Row对应的返回值相同。比如:

SELECT SalesOrderID,CustomerID,RANK() OVER (ORDER BY CustomerID) AS RowNum
FROM Sales.SalesOrderHeader

下面是相应的查询结果:

对于RANK(),还有一点需要说明的是,它的回返值不是连续的, 比如第五条记录的Row_Num是5而不是2。如果想实现这样需求,就需要用下面一个Function:DENSE_RANK()。

3.          3. DENSE_RANK()

DENSE_RANK()实现了一个连续的Ranking。比如下面的SQL:

SELECT SalesOrderID,CustomerID,DENSE_RANK() OVER (ORDER BY CustomerID) AS RowNum
FROM Sales.SalesOrderHeader

就来产生如下的查询结果:

4. NTILE()

上面我们说到划分梯队的问题,这样的问题可以通过NTILE() Function来实现。比如我们现在按照CustomerID排序,把CustomerID为1和2的划分到3梯队中:

SELECT SalesOrderID,CustomerID,NTILE(3) OVER (ORDER BY CustomerID) AS RowNum
FROM Sales.SalesOrderHeader
WHERE CustomerID <3

其查询结果为:

我们可以看到,一共12条记录,划分为3组,平均下来每组4条记录。

5.          5.PARTITION BY

上面提到的所有Ranking都是基于真个结果基的。而有的时候我们需要将真个结果集按照某个Column 进行分组,进行基于组的Ranking。这就需要PARTITION BY了。PARTITION BY置于OVER Clause中,和ORDER BY 平级。

比如下面的SQL将Order记录按照CustomerID进行分组,在每组中输出排名(安OrderDate排序):

SELECT SalesOrderID,CustomerID,RANK() OVER (PARTITION BY CustomerID ORDER BY OrderDate) AS RowNum
FROM Sales.SalesOrderHeader

相应的查询结果:

SqlServer 语法的更多相关文章

  1. Sqlite基础及其与SQLServer语法差异

    1 TOP 这是一个大家经常问到的问题,例如在SQLSERVER中可以使用如下语句来取得记录集中的前十条记录: SELECT TOP 10 * FROM [index] ORDER BY indexi ...

  2. SQLServer语法常用总结

    1. 有时候查看SQL的时候表名或者字段名需要加[],这是因为有时候你的表名或者字段名正好与sqlserver的保留字段重了 比如:有一个user表,直接select会报错 select * from ...

  3. Sqlserver 语法总结

    修改列类型 alter table PRO_Element_b alter column matname varchar(1024) 更改一个表中的数据到另外一个表中 update a set a.n ...

  4. mysql & sqlserver语法差异

    isnull   vs   ifnull dateadd  vs date_add limit vs  top

  5. oracle与sqlserver利用函数生成年月日加流水号

    最近在做oracle相关的项目,刚接触oracle,与sqlserver语法上还是有区别的 sqlserver : 示例:FX+当前年月日+00001 如下图流水号实力所示 原理: 首先 'FX'是固 ...

  6. sqlserver可将字符转成数字再进行sum,如果varchar类型中存放的都是数字

    sqlserver语法: select sum(cast(score as int)) as score from 表名; 注意:int是整型,在实际操作中根据自己需要的类型转换.

  7. Access与SQL Server 语法差异

    序号 简述 Access语法 SqlServer语法 Oracle语法 解决方案 01 系统时间 Now(),Date() GETDATE() SYSDATE GetSysTimeStr 02 连接字 ...

  8. 『片段』OracleHelper (支持 多条SQL语句)

    C# 调用 Oracle 是如此尴尬 >System.Data.OracleClient.dll —— .Net 自带的 已经 过时作废. >要链接 Oracle 服务器,必须在 本机安装 ...

  9. 回家前的挣扎——SQLite增删改查

    引言 最后一天,公司就两个人,也不知道弄点什么,就在网上找了Sqlite的文档,看了看,这里也是现学现卖,给自己找点事做,感觉时间过得还是比较快的,不然焦急等待,滋味不好受啊. SQLite简介 SQ ...

随机推荐

  1. springboot + mybatis +pageHelper分页排序

    今天下午写查出来的数据的排序,原来的数据没有排序,现在把排序功能加上...原来用的,是xml中的sql动态传参 ,,1个小数没有弄出来,果断放弃... 网上百度一下,发现用pageHelper  可以 ...

  2. bat——批量删除文件文件夹

    bat批处理,在工作中会带来很多便利. 例如:想删除多个文件夹内的文件夹“Quality”及其子文件 同时删除所有Cyc*文件夹内的所有R00*.tif文件 则可如下操作 先建立父bat文件run_d ...

  3. 【题解】P1171 售货员的难题

    Tags 搜索,状压​. 裸的旅行商问题 #include <stdio.h> #include <string.h> #define re register #define ...

  4. 修改xampp-apache访问目录

    文章转自 https://my.oschina.net/u/3618644/blog/1569972 问题来源: 一般情况下,每个项目占用一个根目录,而不是一个根目录下面有多个项目. 比如说,安装xa ...

  5. 理解MySQL数据库事务

    1. 什么是事务处理? 事务处理是一种机制,它是用来管理必须成批执行的mysql操作.来保证数据库不完整的操作结果. 2. 为什么要使用事务处理? 在使用mysql操作数据的过程中,如果只是简单的中小 ...

  6. Linux内核入门到放弃-模块-《深入Linux内核架构》笔记

    使用模块 依赖关系 modutils标准工具集中的depmod工具可用于计算系统的各个模块之间的依赖关系.每次系统启动时或新模块安装后,通常都会运行该程序.找到的依赖关系保存在一个列表中.默认情况下, ...

  7. Java的get、post请求

    URLConnection package com.shuzf.http; import java.io.BufferedReader; import java.io.IOException; imp ...

  8. Redhat6.4安装Oracle 11gr2 64位 注意事项

    安装步骤略, 安装步骤参考:https://www.cnblogs.com/jhlong/p/5442459.html 注意的是,会出现找不到一些依赖库,我根据光盘已有的库安装了所有64位的依赖库,强 ...

  9. 软件工程(GZSD2015) 第二次作业小结

    第二次作业,从4月7号开始,陆续开始提交作业.根据同学们提交的作业报告,相比第一次作业,已经有了巨大改变,大家开始有了完整的实践,对那些抽象的名词也开始有了直观的感受,这很好.然后有一些普遍存在的问题 ...

  10. Vue——报错总结

    [Vue warn]: Cannot find element: #app [报错原因] 1. 把对应js放在了head标签里面,页面没有加载完成就进行渲染,导致找不到#app. 2.加了<te ...