窗口函数之排名函数与分析函数

窗口函数中的排名函数与分析函数实在是太好用了,尤其是row_number和lead

全局表如下:
窗口函数之排名函数与分析函数_第1张图片

排名函数

1.row_number

          ROW_NUMBER() over (partition by name order by testid)       (partition by 是可选的)   其他排名函数相同
 按照order排序  返回顺序       
select ROW_NUMBER() over(order by col1) rowNumber,* from t1
窗口函数之排名函数与分析函数_第2张图片
select ROW_NUMBER() over(partition by col1 order by col1) rowNumber,* from t1
窗口函数之排名函数与分析函数_第3张图片

2.rank

按照order排序 返回排名,相同情况下排名相同
select rank() over(order by col1) rank_,* from t1
窗口函数之排名函数与分析函数_第4张图片
select rank() over(partition by col1 order by col1) rank_,* from t1
窗口函数之排名函数与分析函数_第5张图片

3.dense_rank

看图比较和rank的区别
select dense_rank() over(order by col1) rank_,* from t1
窗口函数之排名函数与分析函数_第6张图片

4.ntile

ntile函数,将数据强制分成n份,可结合case when 转为阶段百分比
例如:25%,50%等
select ntile(4) over(order by col1) rank_,* from t1
窗口函数之排名函数与分析函数_第7张图片

分析函数

1.cume_dist

计算累计分布 ,计算某指定值在一组值中的相对位置,值相同的情况按照最后一个值的位置计算
select cume_dist() over(order by col1) as cume_dist,* from t1
窗口函数之排名函数与分析函数_第8张图片

2.first_value 3.last_value

取首尾数据
这个我在别的地方看到一个很好的解释,就不再重复实验了
例:查询部门最早发生销售记录日期和最近发生的销售记录日期
SQL> select *from criss_sales order by dept_id,sale_date;
 
DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT
------- ----------- ---------- -----------
D01     2014/3/4    G00                700
D01     2014/4/8    G01                200
D01     2014/4/30   G03                800
D01     2014/5/4    G02                 80
D01     2014/6/12   G01        
D02     2014/3/6    G00                500
D02     2014/4/8    G02                100
D02     2014/4/27   G01                300
D02     2014/5/2    G03                900
SQL> select
  2     dept_id
  3    ,sale_date
  4    ,goods_type
  5    ,sale_cnt
  6    ,first_value(sale_date) over (partition by dept_id order by sale_date) first_value
  7    ,last_value(sale_date) over (partition by dept_id order by sale_date desc) last_value
  8  from criss_sales;
 
DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT FIRST_VALUE LAST_VALUE
------- ----------- ---------- ----------- ----------- -----------
D01     2014/3/4    G00                700 2014/3/4    2014/3/4
D01     2014/4/8    G01                200 2014/3/4    2014/4/8
D01     2014/4/30   G03                800 2014/3/4    2014/4/30
D01     2014/5/4    G02                 80 2014/3/4    2014/5/4
D01     2014/6/12   G01                    2014/3/4    2014/6/12
D02     2014/3/6    G00                500 2014/3/6    2014/3/6
D02     2014/4/8    G02                100 2014/3/6    2014/4/8
D02     2014/4/27   G01                300 2014/3/6    2014/4/27
D02     2014/5/2    G03                900 2014/3/6    2014/5/2

看结果first_value()很直观,不用多解释
但是,last_value()值,部门D01不是应该为2014/6/12,部门D02不是应该为2014/5/2吗?为什么会每条记录都不一样?
可以这样去理解:last_value()默认统计范围是 rows between unbounded preceding and current row
验证一下:
SQL> select
  2     dept_id
  3    ,sale_date
  4    ,goods_type
  5    ,sale_cnt
  6    ,first_value(sale_date) over (partition by dept_id order by sale_date) first_value
  7    ,last_value(sale_date) over (partition by dept_id order by sale_date desc) last_value
  8    ,last_value(sale_date) over (partition by dept_id order by sale_date rows between unbounded preceding and unbounded following) last_value_all
  9  from criss_sales;
 
DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT FIRST_VALUE LAST_VALUE  LAST_VALUE_ALL
------- ----------- ---------- ----------- ----------- ----------- --------------
D01     2014/3/4    G00                700 2014/3/4    2014/3/4    2014/6/12
D01     2014/4/8    G01                200 2014/3/4    2014/4/8    2014/6/12
D01     2014/4/30   G03                800 2014/3/4    2014/4/30   2014/6/12
D01     2014/5/4    G02                 80 2014/3/4    2014/5/4    2014/6/12
D01     2014/6/12   G01                    2014/3/4    2014/6/12   2014/6/12
D02     2014/3/6    G00                500 2014/3/6    2014/3/6    2014/5/2
D02     2014/4/8    G02                100 2014/3/6    2014/4/8    2014/5/2
D02     2014/4/27   G01                300 2014/3/6    2014/4/27   2014/5/2
D02     2014/5/2    G03                900 2014/3/6    2014/5/2    2014/5/2
 
全统计的情况下得到的last_value()值,部门D01为2014/6/12,部门D02为2014/5/2

4.lag  5.lead

取第前n行或第后n行,越界值用默认值代替
三个参数 列名  偏移量  默认值
SQL> select *  from kkk;                                          
                                                            
        ID NAME                                                   
---------- --------------------                                   
         1 1name                                                  
         2 2name                                                  
         3 3name                                                  
         4 4name                                                  
         5 5name                                                  
                                                                  
SQL> select id,name,lag(name,1,0) over ( order by id )  from kkk; 
                                                                  
        ID NAME                 LAG(NAME,1,0)OVER(ORDERBYID)      
---------- -------------------- ----------------------------      
         1 1name                0                                 
         2 2name                1name                             
         3 3name                2name                             
         4 4name                3name                             
         5 5name                4name                             
                                                                  
SQL> select id,name,lead(name,1,0) over ( order by id )  from kkk;
                                                                  
        ID NAME                 LEAD(NAME,1,0)OVER(ORDERBYID)     
---------- -------------------- -----------------------------     
         1 1name                2name                             
         2 2name                3name                             
         3 3name                4name                             
         4 4name                5name                             
         5 5name                0                                 
                                                                  
SQL>  
SQL> select id,name,lead(name,2,0) over ( order by id )  from kkk;                                                            
                                                                  
        ID NAME                 LEAD(NAME,2,0)OVER(ORDERBYID)     
---------- -------------------- -----------------------------     
         1 1name                3name                             
         2 2name                4name                             
         3 3name                5name                             
         4 4name                0                                 
         5 5name                0                                 
                                                                  
SQL> 
SQL> select id,name,lead(name,1,'alsdfjlasdjfsaf') over ( order by id )  from kkk;                                                             
                                                                                  
        ID NAME                 LEAD(NAME,1,'ALSDFJLASDJFSAF')                    
---------- -------------------- ------------------------------                    
         1 1name                2name                                             
         2 2name                3name                                             
         3 3name                4name                                             
         4 4name                5name                                             
         5 5name                alsdfjlasdjfsaf           

你可能感兴趣的:(SQL)