• 重学SQL Server 笔记(二)


      对于top关键字,你也许很熟悉他的用法,但你知道top查询返回的是一个表结果还是游标呢?

      当使用top的,同一个order by字句既担当了为top决定行的逻辑优先顺序的角色,同时也担当了它的常规角色(展示数据),只是最终生成的结果由表变成了具有固定顺序的游标。

       用法有下面三种:1、关键字 percent,SQL Server会按照百分比计算应该返回的的满足条件的行数(向上取整);

      用法  select top 1 percent orderid from ordervalues。

               2、选择需要的前几行,常用于分页;

      用法 select top 10 orderid from ordervalues。

            3、返回与top n行中最后一行的排序值相同的其他所有行,须添加 with ties选项,如果排序值有多个,则以最后一个排序值为准,这里为custid。

      用法 select top(5) with ties orderid,orderdate,custid,empid
           from orders
                  order by empid desc,custid

      over子句,用于为行定义一个窗口,以便进行特定的运算。我们可以把行的窗口简单的认为是运算将要操作的一个行的集合。由于over子句可以为聚合函数和排名函数提供一个行的窗口,这些函数也称为开窗函数。带有空的圆括号的over子句会提供所有行进行计算,这里的所有行并不一定是在from 子句中出现的那些表中的所有行,而是在from、where、group by,以及having处理阶段才完成后仍然可以用的那些行。那么,什么地方才可以用over子句呢?? answer就是只有在select和order by处理阶段。

      以下例句中的OrderValues是一个视图(其中数据可以在我的上一篇博文可以下载)。创建此视图的语句为

    CREATE VIEW OrderValues
    AS
    
    SELECT O.orderid, O.custid, O.empid, O.shipperid, O.orderdate,
      CAST(SUM(OD.qty * OD.unitprice * (1 - discount))
           AS NUMERIC(12, 2)) AS val
    FROM Orders AS O
      JOIN OrderDetails AS OD
        ON O.orderid = OD.orderid
    GROUP BY O.orderid, O.custid, O.empid, O.shipperid, O.orderdate;

     

      请看下面Sql语句。其中sum(val) over() as totalValue表示返回当前所有行的val字段的和,如果我们想得到当前行具有相同custid值得val之和,那么则可以用partition  by 字句指定求和的关键字。

    1 select * from OrderValues;
    2 select orderid,custid,val,
    3     sum(val) over() as totalvalue,
    4     sum(val) over(partition by custid) as custtotalvalue
    5 from OrderValues;

       当然,over子句的一个优点是能够在返回基本行的同时,可以将聚合函数和基本列共同使用。比如下面Sql语句。

    1 select orderid,custid,val,
    2     100.*val/sum(val) over() as pctall,
    3     100.*val/sum(val) over(partition by custid) as pctust
    4 from ordervalues;

      不仅如此,over子句也支持四种排名函数,row_number(),rank(),dense_rank(),ntile,如下面Sql语句。

    1 select orderid,custid,val,
    2        row_number() over(order by val) as rownum,
    3        rank() over(order by val) as rank,
    4        dense_rank() over(order by val) as dense_rank,
    5        ntile(10) over(order by val) as ntile
    6 from ordervalues
    7 order by val

      其中,row_number函数用于为子查询的结果集中的各行分配递增的序列号,其逻辑顺序通过over子句中的order by语句制定,因此,order by子句的字段的值最好在数据库中是唯一的。NTILE函数可以把结果中的行关联到组,NTILE(n)中的n表示制定组的数目,并为每一行分配一个所属组的编号,因此组的大小是830/10=83,即第一个组里面有83行数据。当然,排名函数也支持partition by语句。rank()与dense_rank()可以为具有相同逻辑排序值得所有行产生相同的排名。这两个函数的区别是,rank()表示之前有多少行具有更低的排序值,而密集排名函数则表示之前有多少个更低的排序值,注意一个是行,一个值。

  • 相关阅读:
    C# FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址。"的错误
    ESP32 学习笔记
    ESP32 学习笔记
    C# 实现窗口无边框,可拖动效果
    C# 获取IP地址
    C# 实现程序开机自启动
    C# 设置程序最小化到任务栏右下角,鼠标左键单击还原,右键提示关闭程序
    C# 生成机器码
    C# 隐藏窗口标题栏、隐藏任务栏图标
    C# 测量程序运行时间
  • 原文地址:https://www.cnblogs.com/xianrongbin/p/2779827.html
Copyright © 2020-2023  润新知