zoukankan      html  css  js  c++  java
  • oracle 分析函数 keep(dense_rank first/last)

    SQL : select * from crisis_sales where dept_id = 'D02' order by sale_date;

    DEPT_ID  SALE_DATE  GOODS_TYPE  SALE_CNT

    ----------------------------------------------------------------------

    min(sale_cnt)  keep(dense_rank first order by sale_date) min_early_date.

    这句SQL是用来查找最早的(FIRST)SALE_DATE 中,SALE_CNT 最小的(MIN)一个.

    因为在同一个sale_date 中,可能存在多条sale记录,所以需要用min/max 函数进行聚合。

    1. keep() 是保存满足括号内条件的记录,即keep括号内的记录,可能存在多条first or last 的记录。

    2. dense_rank 是排序策略。

    3. first/last 是筛选策略

    总之,使用keep() 函数一般的格式为 :

    1. max() keep(dense_rank first/last order by )

    2. min() keep(dense_rank first/last order by)

    SQL 分析函数之KEEP (DENSE_RANK FIRST/LAST)

    原创                2016年04月19日 14:53:23

    场景

    在业务数据中可能遇到这样的需求。希望获取部门内年龄最小的人中,工资最高的记录。此时就需要使用KEEP(DENSE_RANK FIRST/LAST)来处理数据了。

    使用

    首先构造一下临时数据。

    1. WITH workers AS(   
    2.   SELECT 'DOM1' dept, 'zhangsan' names , 23 age, 4000 salaries FROM dual UNION ALL   
    3.   SELECT 'DOM1' dept, 'lisi' names     , 35 age, 9000 salaries FROM dual UNION ALL   
    4.   SELECT 'DOM2' dept, 'wangwu' names   , 26 age, 6500 salaries FROM dual UNION ALL   
    5.   SELECT 'DOM2' dept, 'maliu' names    , 28 age, 6000 salaries FROM dual UNION ALL   
    6.   SELECT 'DOM2' dept, 'zhaoqi' names   , 26 age, 5000 salaries FROM dual UNION ALL   
    7.   SELECT 'DOM1' dept, 'liba' names     , 23 age, 3000 salaries FROM dual    
    WITH workers AS(  
      SELECT 'DOM1' dept, 'zhangsan' names , 23 age, 4000 salaries FROM dual UNION ALL  
      SELECT 'DOM1' dept, 'lisi' names     , 35 age, 9000 salaries FROM dual UNION ALL  
      SELECT 'DOM2' dept, 'wangwu' names   , 26 age, 6500 salaries FROM dual UNION ALL  
      SELECT 'DOM2' dept, 'maliu' names    , 28 age, 6000 salaries FROM dual UNION ALL  
      SELECT 'DOM2' dept, 'zhaoqi' names   , 26 age, 5000 salaries FROM dual UNION ALL  
      SELECT 'DOM1' dept, 'liba' names     , 23 age, 3000 salaries FROM dual   
    )
    在这六条数据中,我们期望的数据是:(DOM1,4000)和(DOM2,6500)。

    我们的sql如下:

    1. SELECT w.dept, MAX(w.salaries) KEEP(DENSE_RANK FIRST ORDER BY w.age) max_salary FROM workers w WHERE 1=1 GROUP BY dept; 
    SELECT w.dept, MAX(w.salaries) KEEP(DENSE_RANK FIRST ORDER BY w.age) max_salary FROM workers w WHERE 1=1 GROUP BY dept;

    此图就是我们的查询结果。

    解释

    KEEP

    keep的意思就是“保持”,会保持满足括号内条件的记录,用ORDER BY 后自然会有FIRST和LAST了。

    DENSE_RANK

    DENSE_RANK是排序策略。例如,它会将两个第二名排在第一名之后,之后还是第三名排在第二名之后。

    FIRST/LAST

    FIRST/LAST就是对数据进行筛选了。这里我们筛选age最小的记录。当然不止一条了。然后使用MAX()选取最大salaries了。

    延伸

    同样的,年龄最大人中的最低工资查询如下:

    1. SELECT w.dept, MIN(w.salaries) KEEP(DENSE_RANK LAST ORDER BY w.age) min_salary FROM workers w WHERE 1=1 GROUP BY dept; 
  • 相关阅读:
    文艺平衡树
    [BJOI2010] 严格次小生成树
    BZOJ3864 hero meet devil
    [NOI2010]能量采集(莫比乌斯反演)
    陌上花开(三维偏序)(cdq分治)
    树状数组套trie 模板
    SDOI2010粟粟的书架
    OI计算几何 简单学习笔记
    OI知识点|NOIP考点|省选考点|教程与学习笔记合集
    悬线法学习笔记
  • 原文地址:https://www.cnblogs.com/xiaojianblogs/p/8046887.html
Copyright © 2011-2022 走看看