zoukankan      html  css  js  c++  java
  • 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():不关心行具有相同的值的问题,持续递增,类似于IDENTITYRANK():允许行具有相同的值的时候相同的排名,在遇到不同的值得时候重新进行ROWNUMBER()排名。
              例如N个相同的值排名为1, 那么在N+1的时候排名采用ROWNUMBER()的值也就是N+1.
    DENSE_RANK():允许行具有相同的时候相同的排名,在遇到不同的值得时候采用上次的排名进行+1处理。 
             例如N个相同的值排名为1,那么在N+1的时候排名 采用上次的排名值也就是N+1.
    NTILE(X):这个函数可以说很少使用。几乎是个废柴,看上面的代码就明白了。

       

     

    性别:男 爱好:女 生辰:93 死亡:未知

     

     

     

    分类: SQL2012

     

     

    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}	{1};	{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}	{1};	{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);

    WebRequestHandlerHttpMessageHandler派生。您还可以通过从HttpMessageHandler派生插入自定义消息处理程序中。有关详细信息,请参阅HTTP消息处理程序(暂未实现)

    总结

    本文来源链接http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client

    一步一步的学下来,还是很有收获的。其中有些地方不太理解还需要慢慢的消化了。

     
     
  • 相关阅读:
    Prim+堆优化
    Tarjan缩点+建新图
    CF482A
    CF545C
    CF570B
    Python 入门2 list介绍
    Python 入门1 上传代码
    黑客与画家 第十三章
    黑客与画家 第十一章
    黑客与画家 第五章
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3442429.html
Copyright © 2011-2022 走看看