四、            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. 【转】Android辅助功能AccessibilityService自动全选择文字粘贴模拟输入

    网上找了很久AccessibilityService全选文字的方法,一直没找到,自己研究了半天,分享出来. /** * 输入文本 */ public void inputText(List<St ...

  2. ServerSocketChannel、SocketChannel、Selector等概念04

    java.nio包中的主要类ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信.SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通 ...

  3. Spring Cloud:统一异常处理

    在启动应用时会发现在控制台打印的日志中出现了两个路径为 {[/error]} 的访问地址,当系统中发送异常错误时,Spring Boot 会根据请求方式分别跳转到以 JSON 格式或以界面显示的 /e ...

  4. Office开发必备知识----为什么要释放非托管Com资源

    https://www.cnblogs.com/Charltsing/p/RealeaseComObject.html QQ:564955427 目前,国内Office插件开发的风头正盛,很多VBAe ...

  5. JVM调优:HotSpot JVM垃圾收集器

    HotSpot JVM垃圾收集器 - Snooper - 博客园https://www.cnblogs.com/snooper/p/8718478.html

  6. vue报错如log,如果其他项目运行没问题,很有可能是代码错误 加externals报错

  7. IE 11 flex布局兼容性问题 ---- 不支持min-height 和flex:1

    由于最近项目要嵌入其它平台,所以要做IE11 的兼容,那就用IE11打开网页看一看,一看吓一跳,页脚直接到了页眉的下面,并把主要内容覆盖了,也就是stick footer 布局失效了,我写了一个简易的 ...

  8. kubernetes 报错汇总

    一. pod的报错: 1. pod的容器无法启动报错: 报错信息: Normal SandboxChanged 4m9s (x12 over 5m18s) kubelet, k8sn1 Pod san ...

  9. codeforces选做

    收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...

  10. 仙人掌&圆方树学习笔记

    仙人掌&圆方树学习笔记 1.仙人掌 圆方树用来干啥? --处理仙人掌的问题. 仙人掌是啥? (图片来自于\(BZOJ1023\)) --也就是任意一条边只会出现在一个环里面. 当然,如果你的图 ...