来源于:http://blog.itpub.net/28929558/viewspace-1182183/

销售表:
SQL> select * from criss_sales where dept_id = 'D02' order by sale_date ;
 
DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT
------- ----------- ---------- -----------
D02     2014/3/6    G00                500
D02     2014/3/6    G01                430
D02     2014/4/8    G02                100
D02     2014/4/27   G01                300
D02     2014/5/2    G03                900

此时有个新需求,希望查看部门 D02 内,销售记录时间最早,销售量最小的记录。

即希望得到这样的信息
D02     2014/3/6    G01                430

这样,就需要用keep(dense_rank first/last)来帮助处理

SQL> select
  2      dept_id
  3     ,min(sale_cnt)keep ( dense_rank first order by sale_date) min_early_date
  4  from criss_sales
  5  where dept_id = 'D02'
  6  group by dept_id
  7  ;
 
DEPT_ID  MIN_EARLY_DATE
------- ----------
D02            430

关于使用keep(dense_rank first/last) 会有一些疑问
1.keep(dense_rank first/last) 这句话的含义是什么?
2.为什么要使用min ?
3.为什么使用dense_rank ? rank不可以吗?

关于问题1:
  keep 字面意思就是'保持',也就是说保存满足keep()括号内条件的记录
       这里我们应该可以想象到,会有多条记录的情况,即存在多个last或first的情况)
  dense_rank 是排序策略
  first/last 是筛选策略
  
关于问题2:
使用min的原因是让最后得到的结果唯一,因为有时会存在多个last或first的情况。
例子中:
DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT
------- ----------- ---------- -----------
D02     2014/3/6    G00                500
D02     2014/3/6    G01                430
这两条记录,同时满足keep的条件,通过 min(sale_cnt) 我们就得到了唯一的值 
   D02     2014/3/6    G01                430
  下面我们加上MAX 与 MIN对比下
  SQL> select
  2      dept_id
  3     ,min(sale_cnt)keep ( dense_rank first order by sale_date) min_early_date
  4     ,max(sale_cnt)keep ( dense_rank first order by sale_date) max_early_date
  5  from criss_sales
  6  where dept_id = 'D02'
  7  group by dept_id
  8  ;
 
DEPT_ID MIN_EARLY_DATE MAX_EARLY_DATE
------- -------------- --------------
D02                430            500

 很显然 max 取到了两条记录的较大值!

关于问题3:
先看一下换成rank的情况吧
select
    dept_id
   ,min(sale_cnt)keep ( rank first order by sale_date) min_early_date
   ,max(sale_cnt)keep ( rank first order by sale_date) max_early_date
from criss_sales
where dept_id = 'D02'
group by dept_id
 
ORA-02000: 缺失 DENSE_RANK 关键字 

换成rank以后直接报错了,至于原因,我的理解是rank不能表示记录排序的相对顺序
  例如: 记录   rank   dense_rank
          100    1     1
          100    1     1
          95     3     2
第三条记录与第一条和第二条记录的相对位置应该差1,但是用rank无法表示这一点。
感觉rank应该也能实现first/last的筛选,但是oracle似乎并没允许用rank这样去做。

分析函数——keep(dense_rank first/last)的更多相关文章

  1. [转]oracle分析函数Rank, Dense_rank, row_number

    oracle分析函数Rank, Dense_rank, row_number 分析函数2(Rank, Dense_rank, row_number)   目录 ==================== ...

  2. Oracle分析函数 — rank, dense_rank, row_number用法

    本文通过例子演示了Oracle分析函数 —— rank, dense_rank, row_number的用法. //首先建score表 create table score( course   nva ...

  3. oracle 分析函数 keep(dense_rank first/last)

    SQL : select * from crisis_sales where dept_id = 'D02' order by sale_date; DEPT_ID  SALE_DATE  GOODS ...

  4. oracle分析函数Rank, Dense_rank, row_number

    http://www.cnblogs.com/wuyisky/archive/2010/02/24/oracle_rank.html 目录=============================== ...

  5. Oracle分析函数-keep(dense_rank first/last)

    select * from criss_sales where dept_id = 'D02' order by sale_date ; 此时有个新需求,希望查看部门 D02 内,销售记录时间最早,销 ...

  6. 部分常见ORACLE面试题以及SQL注意事项

    部分常见ORACLE面试题以及SQL注意事项 一.表的创建: 一个通过单列外键联系起父表和子表的简单例子如下: CREATE TABLE parent(id INT NOT NULL, PRIMARY ...

  7. Oracle 排序分析函数之ROW_NUMBER、RANK和DENSE_RANK

    我们都知道分析函数功能很强大,可能需要写很复杂的标准SQL才能办到或不可能办到的事,使用分析函数却能很容易完成.我们经常会用到排序分析函数,如ROW_NUMBER,RANK,DENSE_RANK.这三 ...

  8. Oracle分析函数-排序排列(rank、dense_rank、row_number、ntile)

    (1)rank函数返回一个唯一的值,除非遇到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名. (2)dense_rank函数返回一个唯一的值, ...

  9. Spark2 Dataset分析函数--排名函数row_number,rank,dense_rank,percent_rank

    select gender,       age,       row_number() over(partition by gender order by age) as rowNumber,    ...

随机推荐

  1. [转]nopcommerce商城系统--如何编写一个插件

    本文转自:http://www.cnblogs.com/ganqiyin/p/3680771.html 原址:http://www.nopcommerce.com/docs/77/how-to-wri ...

  2. 彻底解决mysql中文乱码的办法,修改mysql解压缩版(免安装版或zip版)字符编码

    MySQL会出现中文乱码的原因不外乎下列几点:1.server本身设定问题,例如server字符编码还停留在latin12.table的语系设定问题(包含character与collation)3.客 ...

  3. 【温故而知新-Javascript】使用地理定位

    地理定位(Geolocation)API让我们可以获取用户当前地理位置的信息(或者至少是正在运行浏览器的系统的位置).它不是HTML5规范的一部分,但经常被归组到与HTML5相关的新功能中. 1. 使 ...

  4. 使用C#向ACCESS中插入数据

    使用C#向ACCESS中插入数据   1.创建并打开一个OleDbConnection对象 string strConn = " Provider = Microsoft.Jet.OLEDB ...

  5. 什么是 A 轮融资?有 B轮 C轮么?

    融资的顺序是A轮 B轮 C轮这之前还有天使轮,种子轮,首轮在这之后还有vc/pe,ipo等等,只是一些不同时段的融资 Chen Shu 知乎用户.千叶光.angle LI 等人赞同 就是公司的初卖.再 ...

  6. 在ubuntu14.04设置静态ip

    打开网络的配置文件 sudo vim /etc/network/interfaces 选择网卡,我这里是有线网卡eth0,设置静态ip为192.168.1.108 auto eth0 iface et ...

  7. Volley(二)—— 基本Request对象 & RequestQueue&请求取消

    详细解读Volley(一)—— 基本Request对象 & RequestQueue&请求取消 Volley它非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作, ...

  8. 逗号分隔的字符串转换为行数据(collection)(续)

    逗号分隔的字符串转行数据的存储过程一个: CREATE OR REPLACE FUNCTION SP_YX_SPLIT ( p_list CLOB, p_sep VARCHAR2 := ',' ) R ...

  9. JLOI2016 方

    bzoj4558 真是一道非常excited的题目啊-JLOI有毒 题目大意:给一个(N+1)*(M+1)的网格图,格点坐标为(0~N,0~M),现在挖去了K个点,求剩下多少个正方形(需要注意的是正方 ...

  10. 用django实现一个微信图灵机器人

    微信的post请求格式是xml,所以django需要做的就是将xml请求解析出来,把content发送到图灵机器人接口, 接口返回的json数据把主要内容给解析出来,然后重新封装成xml返回给微信客户 ...