SqlServer 语法
四、 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 语法的更多相关文章
- Sqlite基础及其与SQLServer语法差异
1 TOP 这是一个大家经常问到的问题,例如在SQLSERVER中可以使用如下语句来取得记录集中的前十条记录: SELECT TOP 10 * FROM [index] ORDER BY indexi ...
- SQLServer语法常用总结
1. 有时候查看SQL的时候表名或者字段名需要加[],这是因为有时候你的表名或者字段名正好与sqlserver的保留字段重了 比如:有一个user表,直接select会报错 select * from ...
- Sqlserver 语法总结
修改列类型 alter table PRO_Element_b alter column matname varchar(1024) 更改一个表中的数据到另外一个表中 update a set a.n ...
- mysql & sqlserver语法差异
isnull vs ifnull dateadd vs date_add limit vs top
- oracle与sqlserver利用函数生成年月日加流水号
最近在做oracle相关的项目,刚接触oracle,与sqlserver语法上还是有区别的 sqlserver : 示例:FX+当前年月日+00001 如下图流水号实力所示 原理: 首先 'FX'是固 ...
- sqlserver可将字符转成数字再进行sum,如果varchar类型中存放的都是数字
sqlserver语法: select sum(cast(score as int)) as score from 表名; 注意:int是整型,在实际操作中根据自己需要的类型转换.
- Access与SQL Server 语法差异
序号 简述 Access语法 SqlServer语法 Oracle语法 解决方案 01 系统时间 Now(),Date() GETDATE() SYSDATE GetSysTimeStr 02 连接字 ...
- 『片段』OracleHelper (支持 多条SQL语句)
C# 调用 Oracle 是如此尴尬 >System.Data.OracleClient.dll —— .Net 自带的 已经 过时作废. >要链接 Oracle 服务器,必须在 本机安装 ...
- 回家前的挣扎——SQLite增删改查
引言 最后一天,公司就两个人,也不知道弄点什么,就在网上找了Sqlite的文档,看了看,这里也是现学现卖,给自己找点事做,感觉时间过得还是比较快的,不然焦急等待,滋味不好受啊. SQLite简介 SQ ...
随机推荐
- LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)
写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...
- Node、TS、Koa学习笔记
这样定义可以轻松拿到gender属性 这样定义,函数内显示没有gender 这种方法能得到gender但是函数内部没有gender 这种方式能到gender 但是在函数里施symbel属性,外部不能访 ...
- 关于idea在运行web项目时部署的位置
(转) 以前一直很好奇,在idea中运行tomcat,把项目部署到其中,运行起来,然后我去tomcat目录下去看,根本找不到我部署的项目 那我的项目是咋运行的啊… - - 后来我就查啊查 ,纠结啊纠结 ...
- SQL其他常用的语句
阅读目录 一:汇总数据 1.理解AVG函数 2.理解COUNT()函数 3.理解max()函数 4.理解min()函数 5.理解sum()函数 二:分组数据 1 创建分组(group by) 2 HA ...
- Sklearn中的回归和分类算法
一.sklearn中自带的回归算法 1. 算法 来自:https://my.oschina.net/kilosnow/blog/1619605 另外,skilearn中自带保存模型的方法,可以把训练完 ...
- Java Lucene入门
1.lucene版本:7.2.1 pom文件: <?xml version="1.0" encoding="UTF-8"?> <project ...
- 基于 HTML5 WebGL 的 3D 工控裙房系统
前言 工业物联网在中国的发展如火如荼,网络基础设施建设,以及工业升级的迫切需要都为工业物联网发展提供了很大的机遇.中国工业物联网企业目前呈现两种发展形式并存状况:一方面是大型通讯.IT企业的布局:一方 ...
- VBA Editor Addins --> VBE插件模板开发众筹
https://www.cnblogs.com/Charltsing/p/VBEAddins.html QQ:564955427 8月8日测试版功能说明 1.VBE菜单的创建 2.toolwindow ...
- photoshop快速把新照片制作成老照片教学
原图 步骤1 在photoshop中找开需要处理的图片,Ctrl+J复制图片,得到图片1. 步骤2 单击图层面板底部的创建新的填充或调整图层图标,添加色调/饱和度调整图层.调整它的饱合度和明度. 步骤 ...
- JAVA获取计算机CPU、硬盘、主板、网络等信息
通过使用第三方开源jar包sigar.jar我们可以获得本地的信息 1.下载sigar.jar sigar官方主页 sigar-1.6.4.zip 2.按照主页上的说明解压包后将相应的文件copy到j ...