zoukankan      html  css  js  c++  java
  • 重学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()表示之前有多少行具有更低的排序值,而密集排名函数则表示之前有多少个更低的排序值,注意一个是行,一个值。

  • 相关阅读:
    idea中导入jquery无法生效解决办法
    如何用最简单的方式解释依赖注入?依赖注入是如何实现解耦的?
    spring的ioc依赖注入的三种方法(xml方式)
    向存在外键的表中插入数据时出错的原因以及插入外键为空的方法
    mysql一条语句添加多条数据
    SQL中distinct的用法
    Java实体对象为什么要实现Serializable接口?
    servlet中使用request.getHeader("referer")获取页面从哪跳转过来的
    java动态拼接sql语句并且执行时给sql语句的参数赋值
    正则表达式
  • 原文地址:https://www.cnblogs.com/xianrongbin/p/2779827.html
Copyright © 2011-2022 走看看