ROWNUMBER()、RANK()、DENSE_RANK()、NTILE1
SQLServer针对排名函数ROWNUMBER()、RANK()、DENSE_RANK()、NTILE的研究!~
相信大家在软件工程中经常会遇到对某些数据进行排名的问题,尤其是对于电子商务的HR来说“大手笔”是非常具有潜在价值的!~至于都有哪些价值这个超出本文的范畴不予进行说明,但是不得不说的是每一个精明的HR以下类似的需求:
我需要系统告诉我,截止到目前为止,近几个月内销售人员的订单交易数量排名、奖金排名(对内部员工员工)
我需要系统告诉我,截止到目前为止,商品热度的排名、购买力度的排名、充值力度的排名、提款力度的排名,相关地区的的排名(对客户)
对于SQL新人来说,第一个想到的函数TOP配合ROW_NUMBER()、ORDER BY,如果你用了这3个配合,那么恭喜你,You're Wrong!
因为上述的情况,可能会发生相同数据的排名,那么一旦排名的数据发生相同,因为ROWNUMBER()类似于IDENTITY(起始1,自增1)所以对排名的准确性就不那么明确了。
下面来看具体的例子:
基础数据准备:
/*以下代码执行完成只是为了讲解说明,执行完成需要刷新下IntelliSence缓存,更新下当前智能提示
*键盘快捷键 Ctrl+Shift+R。
*@author 系统管理员-咔咔
*@time 2013-11-25
*/
USE MyDB;
IF EXISTS (Select * From sys.objects Where name =N'EmployeOrdersCount' And Type In ('S','U'))
DROP TABLE EmployeOrdersCount
ELSE
CREATE TABLE EmployeOrdersCount --员工订单统计
(
Id INT PRIMARY KEY IDENTITY,--主键ID
EmployeNO NVARCHAR(15), --员工编号
OrdersCount INT, --订单数量
)
INSERT INTO EmployeOrdersCount(EmployeNO,OrdersCount)
VALUES('100',100),('102',100),('103',100),('104',100),
('105',100),('106',99),('107',99),('108',99),('109',98),
('110',98),('111',97),('112',96),('113',100)
执行命令:
SELECT ROW_NUMBER() OVER(ORDER BY OrdersCount desc) AS 'RowNumber',
RANK() OVER(ORDER BY OrdersCount desc) AS 'Rank',
DENSE_RANK() OVER(ORDER BY OrdersCount desc) AS 'Dense_rank',
NTILE(4) OVER(ORDER BY OrdersCount desc) AS 'ntile'
,EmployeNO, OrdersCount
FROM EmployeOrdersCount
结果如下:
RowNumber Rank Dense_rank ntile EmployeNO OrdersCount
-------------------- -------------------- -------------------- -------------------- --------------- -----------
1 1 1 1 100 100
2 1 1 1 102 100
3 1 1 1 103 100
4 1 1 1 104 100
5 1 1 2 105 100
6 1 1 2 113 100
7 7 2 2 106 99
8 7 2 3 107 99
9 7 2 3 108 99
10 10 3 3 109 98
11 10 3 4 110 98
12 12 4 4 111 97
13 13 5 4 112 96 (13 行受影响)
结论如下:
ROWNUMBER():不关心行具有相同的值的问题,持续递增,类似于IDENTITY。
RANK():允许行具有相同的值的时候相同的排名,在遇到不同的值得时候重新进行ROWNUMBER()排名。
例如N个相同的值排名为1, 那么在N+1的时候排名采用ROWNUMBER()的值也就是N+1.
DENSE_RANK():允许行具有相同的时候相同的排名,在遇到不同的值得时候采用上次的排名进行+1处理。
例如N个相同的值排名为1,那么在N+1的时候排名 采用上次的排名值也就是N+1.
NTILE(X):这个函数可以说很少使用。几乎是个废柴,看上面的代码就明白了。
Asp.Net Web API 导航
Asp.Net Web API第一课:入门http://www.cnblogs.com/aehyok/p/3432158.html
Asp.Net Web API第二课:CRUD操作http://www.cnblogs.com/aehyok/p/3434578.html
前言
本教程演示从一个控制台应用程序,使用HttpClient调用Web API。我们也将使用上一个教程中建立的Web API。你可以直接在http://www.cnblogs.com/aehyok/p/3434578.html这篇文章中找到相应的下载链接,就可以获得建立的Web API。
我们还是通过VS2013创建的测试项目。本教程示例代码下载链接http://pan.baidu.com/s/1mrObX
建立控制台项目
首先建立一个简单的控制台应用程序,然后通过Nuget来获得Microsoft.AspNet.WebApi.Client。
通过搜索,然后点击安装即可安装Web API 客户端库。
在项目中添加Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CallWebApi
{
public class Product
{
public string Name { get; set; }
public double Price { get; set; }
public string Category { get; set; }
}
}
这个类创建了一个数据对象,HTTPClient可以在HTTP 请求正文中写入它,也可以从HTTP响应正文中读取它。
初始化HTTPClient
创建一个新的HttpClient示例,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks; namespace CallWebApi
{
class Program
{
static void Main(string[] args)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:4115/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
}
}
这是上一教程中的应用程序执行效果展示
所以我们上面的代码
client.BaseAddress = new Uri("http://localhost:4115/");
然后添加了一个json格式的接受表头。它告诉要以 JSON 格式发送数据的服务器接受标头。
通过Http Get方法来获取资源
下面的代码就是,如何通过API来查询产品信息列表。
HttpResponseMessage response = client.GetAsync("api/products").Result;
if (response.IsSuccessStatusCode)
{
var products = response.Content.ReadAsAsync<IEnumerable<Product>>().Result;
foreach (var p in products)
{
Console.WriteLine("{0}\t{1};\t{2}", p.Name, p.Price, p.Category);
}
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
这个GetAsync方法发送了一个Http Get请求。顾名思义,这个GetAsync方法是异步的。它立即返回,无需等待服务端的响应。这个返回值表示一个异步操作的Task对象。当这个操作完成的时候,这个Task.Result属性包含HTTP响应。
如果 HTTP 响应指示成功,这个响应正文将包含一个JSON格式的产品信息列表。为了解析这个列表,需要调用ReadAsAsync。这个方法读取响应正文并且试图范序列化到一个指定的CLR类型。这个方法也是异步的, 因为这个响应的正文可以是任意大的。
api/products的请求标头
api/products的响应标头
api/products的响应正文
最终调用结果在控制台的展示如下
通过一个产品ID获得一个产品信息
///通过一个产品ID获得一个产品信息
response = client.GetAsync("api/products/1").Result;
if (response.IsSuccessStatusCode)
{
var product = response.Content.ReadAsAsync<Product>().Result;
Console.WriteLine("{0}\t{1};\t{2}", product.Name, product.Price, product.Category);
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
媒体类型格式化标识
ReadAsAsync是在System.Net.Http.HttpContentExtensions类中定义的扩展方法。不带参数,它用默认的媒体类型格式标识设置试图去解析这个响应正文。这个默认的格式标识支持JSON、XMl和Form-url-encoded data。
你可以明确的指定媒体类型格式标识来使用。这是非常有用的如果你有一个自定义的媒体类型格式标识。
var formatters = new List<MediaTypeFormatter>() {
new MyCustomFormatter(),
new JsonMediaTypeFormatter(),
new XmlMediaTypeFormatter()
}; resp.Content.ReadAsAsync<IEnumerable<Product>>(formatters);
通过HTTP Post添加一个资源
下面的代码就是发送了一个包含Json格式的Product实体的Post请求。
///HTTP Post请求
var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" };
Uri gizmoUri = null; response = client.PostAsJsonAsync("api/products", gizmo).Result;
if (response.IsSuccessStatusCode)
{
gizmoUri = response.Headers.Location;
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
PostAsJsonAsync 是在System.Net.Http.HttpContentExtensions类中定义的扩展方法。它等效于一下内容:
var product = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" };
MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
HttpContent content = new ObjectContent<Product>(product, jsonFormatter);
var resp = client.PostAsync("api/products", content).Result;
对于XML格式的类型,使用这个PostAsXmlAsync方法。
默认情况下,这个JSON格式表示设置Content-type为“application/json”。你也能明确的指定一个媒体类型。例如: "application/vnd.example.product" 是你的Product实体的媒体类型。你可以设置媒体类型如下:
HttpContent content = new ObjectContent<Product>(product, jsonFormatter,
"application/vnd.example.product+json");
通过HTTP PUT修改一个资源
下面的代码是发送一个PUT请求(接着上面添加的实体进行修改)
gizmo.Price = 99.9;
response = client.PutAsJsonAsync(gizmoUri.PathAndQuery, gizmo).Result;
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
这个PutAsJsonAsync方法像PostAsJsonAsync一样工作,除了它发送一个PUT请求来代替POST之外。
通过HTTP DELETE删除一个资源
到了现在,你可以能够预测怎样发送一个DELETE请求。
///删除一个资源
response = client.DeleteAsync(gizmoUri).Result;
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
和GET一样,删除请求并没有一个请求正文,所以你不需要指定 JSON 或 XML 格式。
Error错误处理
HTTPClient不会抛出一个异常,当它接收到一个错误码的HTTP响应。取而代之的是,这个响应的这个状态码属性中包含这个状态码。此外, 如果状态是成功代码 (200-299 范围中的状态代码),IsSuccessStatusCode属性为true。
上面的例子中我们有使用这个模式:
HttpResponseMessage response = client.GetAsync("api/products").Result;
if (response.IsSuccessStatusCode)
{
// ....
}
如果你更喜欢将错误代码视为异常来看的话,调用这个EnsureSuccessStatusCode方法。如果这个响应状态不是一个成功的状态码,那么这个方法就会抛出一个异常。
try
{
var resp = client.GetAsync("api/products").Result;
resp.EnsureSuccessStatusCode(); // Throw if not a success code. // ...
}
catch (HttpRequestException e)
{
Console.WriteLine(e.Message);
}
配置HttpClient
如果要配置HttpClient,就创建一个WebRequestHandler实例,设置它的属性并将它传递给HttpClient构造函数:
WebRequestHandler handler = new WebRequestHandler()
{
AllowAutoRedirect = false,
UseProxy = false
};
HttpClient client = new HttpClient(handler);
WebRequestHandler从HttpMessageHandler派生。您还可以通过从HttpMessageHandler派生插入自定义消息处理程序中。有关详细信息,请参阅HTTP消息处理程序(暂未实现)
总结
本文来源链接http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
一步一步的学下来,还是很有收获的。其中有些地方不太理解还需要慢慢的消化了。
ROWNUMBER()、RANK()、DENSE_RANK()、NTILE1的更多相关文章
- SQL 序号列ROW_NUMBER,RANK,DENSE_RANK、NTILE
原文:SQL 序号列ROW_NUMBER,RANK,DENSE_RANK.NTILE SQL 2005新增加相关函数 : ROW_NUMBER,RANK,DENSE_RANK.NTILE 窗口函数 O ...
- Oracle 排序分析函数之ROW_NUMBER、RANK和DENSE_RANK
我们都知道分析函数功能很强大,可能需要写很复杂的标准SQL才能办到或不可能办到的事,使用分析函数却能很容易完成.我们经常会用到排序分析函数,如ROW_NUMBER,RANK,DENSE_RANK.这三 ...
- SQL2005四个排名函数(row_number、rank、dense_rank和ntile)的比较
排名函数是SQL Server2005新加的功能.在SQL Server2005中有如下四个排名函数: .row_number .rank .dense_rank .ntile 下面分别介绍一下这四个 ...
- 四个排名函数(row_number、rank、dense_rank和ntile)的比较
排名函数是SQL Server2005新加的功能.在SQL Server2005中有如下四个排名函数: 1.row_number 2.rank 3.dense_rank 4.ntile 下面分别介绍一 ...
- hive的窗口函数ntile、row_number、rank
一.ntile 序列函数不支持window子句 数据准备: cookie1,--, cookie1,--, cookie1,--, cookie1,--, cookie1,--, cookie1,-- ...
- ROW_NUMBER、RANK、DENSE_RANK的用法
--NND,索性把2005的一起帖出来. ROW_NUMBER.RANK.DENSE_RANK的用法 (爱新觉罗.毓华 -- 广东深圳) SQL Server 引入几个新的排序(排名)函数,如ROW_ ...
- row_number()、rank()、dense_rank()、ntile()
原文:row_number().rank().dense_rank().ntile() SQL2005中row_number()等函数的用法 2005比2000新增了几个函数,分别是row_numbe ...
- Rank() 、DENSE_RANK()、NTILE(n)的用法-转
Rank() over()/DENSE_RANK() over()的用法 1.Rank() over()/DENSE_RANK() over() 这两个函数与ROW_NUMBER()函数类似,因为 ...
- sql server 2000 对应 sql server 2005的row_number()、rank()、DENSE_RANK( )、ntile( )等用法
转自CSDN:http://blog.csdn.net/htl258/article/details/4006717 SQL server 2005新增的几个函数,分别是row_number( ).r ...
随机推荐
- 一些有用的javascript实例分析(三)
原文:一些有用的javascript实例分析(三) 10 输入两个数字,比较大小 window.onload = function () { var aInput = document.getElem ...
- NYoj 素数环(深搜入门)
题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=488 深搜模板: void dfs(int 当前状态) { if(当前状态为边界状 ...
- 【iOS发展-70】点菜系统案例:使用文本框inputView和inputAccessoryView串联UIPickerView、UIDatePicker和UIToolBar
(1)效果 (2)先在storyboard中设计界面,然后源码(直接在ViewController中码) #import "ViewController.h" @interface ...
- 从头开始学JavaScript (九)——执行环境和作用域
原文:从头开始学JavaScript (九)--执行环境和作用域 一.执行环境:定义了变量或者函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有与之关联的变量对象. 变量对象:保存着环境中 ...
- maven和libgdx
这一篇是关于maven和libgdx的.本来我准备用gradle(现已有gradle模板了),不过暂时有点小问题,而同时libgdx官方提供了maven支持,为了快速上手还是选用maven了. 博客已 ...
- IOS程序创建view
在IOS程序中创建view有六种方式 首先创建一个GLViewController类,继承UIViewController. 然后进入GLAppDelegate.m,在- (BOOL)applicat ...
- checkbox属性checked="checked"但状态不是勾选状态的解决办法
原因: jQuery API明确说明,1.6+的jQuery要用prop,不能用attr否则无效,尤其是checkBox的checked的属性的判断.
- Ionic项目中使用极光推送-android
对于Ionic项目中使用消息推送服务,Ionic官方提供了ngCordova项目,这个里面的提供了用angularjs封装好的消息推送服务(官方文档),使用的是GitHub上的 PushPlugin ...
- 通过MyEclipse工具直接操作数据库,执行sql语句,方便快捷
原文:通过MyEclipse工具直接操作数据库,执行sql语句,方便快捷 通过MyEclipse操作数据库,执行sql语句使我们不用切换多个工具,直接工作,方便快捷.效果如下: 步骤1:通过MyEcl ...
- 一张地图,告诉你NodeJS命令行调试器语句
NodeJS提供脚本调试. 进入node debug xx.js您可以进入调试模式. 版权声明:本文博客原创文章,博客,未经同意,不得转载.