zoukankan      html  css  js  c++  java
  • oracle 分析函数

          由于工作中经常需要写相对复杂的SQL,在龙哥的指导下,学习了下oracle的分析函数,觉得功能很强大,记录下来,当作学习,先在此谢谢龙哥了。

         一.首先先来了解下什么是Oracle的分析函数吧

       顾名思义,在查询结果的基础上进行分析,也就是说,以一定的方法在一个与当前行相关的结果集子集进行计算。

      

          二.分析函数的列表

          

      三.准备工作 

    1. 表结构和数据
      create table SC
      (
        sno   VARCHAR2(10) not null,
        cno   VARCHAR2(10) not null,
        score NUMBER(4,2)
      )
      
      
      
      insert into sc (SNO, CNO, SCORE)
      values ('s001', 'c001', 78.90);
      
      insert into sc (SNO, CNO, SCORE)
      values ('s002', 'c001', 80.90);
      
      insert into sc (SNO, CNO, SCORE)
      values ('s003', 'c001', 81.90);
      
      insert into sc (SNO, CNO, SCORE)
      values ('s004', 'c001', 60.90);
      
      insert into sc (SNO, CNO, SCORE)
      values ('s001', 'c002', 82.90);
      
      insert into sc (SNO, CNO, SCORE)
      values ('s002', 'c002', 72.90);
      
      insert into sc (SNO, CNO, SCORE)
      values ('s003', 'c002', 81.90);
      
      insert into sc (SNO, CNO, SCORE)
      values ('s001', 'c003', 59.00);
      View Code
    2.  基本语法
      row_number() over (partition by bill_code order by scan_date desc) as r_num;
      
      --这段代码主要是以单号进行分区,按时间进行降序。
      --现在来分析下这段代码:
      
      --1.row_number() 就是一个函数名
      
      --2.over是一个关键字,用于标识分析函数,不然查询分析器不能区分是聚集函数还是分析函数
      
      --3.partition by 是可选分区子句,如果不存在任何分区子句,那么将全部的结果集看作是一个单一的大区
      
      --4.order  by 是可选的order by子句,它指定了计算分析函数时一组内的数据是如何排序的。
      View Code

          3.数据

       


      四.挑选几个比较常用的函数来分析下吧

           Lag               

    /*语法: lag(exp_str,offset,defval) over()
    	   exp_str要取的列
               offset取偏移前的第几行数据
    	   defval:没有符合条件的默认值*/
    
    --执行语法		   
    select t.sno,t.cno,t.score,lag(score, 1, 0) over(order by t.score desc) 
    as preScore from sc t

      
     由图片我们可以看出 lag(score,1,0) over(order by t.score desc),以score进行降序,lag(score,1,0),1代表取上一行score的值,
    如果上一行没有值得话则会为0,由第一条数据可知

      

        Lead

    /*语法: lead(exp_str,offset,defval) over()
    	   exp_str要取的列
               offset取偏移后的第几行数据
    	   defval:没有符合条件的默认值*/
    
    --执行语法		   
    select t.sno,t.cno,t.score,lead(score, 1, 0) over(order by t.score desc) 
    as preScore from sc t
    
    
    
    可参考Lag备注
    --以学号进行分组,然后看下结果集 select t.sno,t.cno,t.score,lead(score, 1, 0) over(partition by sno order by t.score desc) as preScore from sc
    来分析下上面这条SQL,首先先以学号进行一个分组,然后按成绩降序,取下一行的SCORE列,可参考结果集很容易看出区别的

      

        row_number()over

         

    --这个分析函数用得比较多,所以重点讲解下下面的函数
    --row_number()over 对行进行排序并为每一行增加一个唯一的编号


    --假如我们现在有这样的一个需求,取出成绩表中成绩最低的课程号和对应的学生 --如果不使用分析函数 select t.sno,t.cno,t.score from sc t where t.score=( select min(score) from sc where cno='c001' group by cno ) --下面是使用分析函数 select t1.sno, t1.cno, t1.score from (select t.sno,t.cno,t.score, row_number() over(order by score asc) as r_num from sc t where t.cno = 'c001') t1 where t1.r_num = 1 /*虽然这样看不出有这么区别,但假如客户的需求变了,想实现这样,查看当前成绩表中 每们课程最低成绩对应的是哪一位学生的话,传统语法可能写起来相麻烦点,但分析函数写起来就简单粗暴多了。*/ select t1.sno, t1.cno, t1.score from (select t.sno,t.cno,t.score, row_number() over(partition by cno order by score asc) as r_num from sc t) t1 where t1.r_num = 1
        
      将CNO进行一个分区,以成绩进行升序。子查询先执行,这样我们可以得到一个r_num的列,如下图所示
      
            
         由上图我们可知,C001,C002,C003各自为一个分区,以成绩升序排序,这样我们可以看到,
        R_NUM 由小到大依次升序,这样我们就可以在外层取出最低的成绩了。

        sum()over()

    --1.sum()over()简单点的说就是将某个连续字段进行求和
    	   select t.sno,t.cno,t.score,
    	   sum(score)over() as sum_num
    	    from sc t
        
        可以看下sum_num ,这段代码的作用就是将 score这个字段进行一个求和,得到一个集,显示出来而已
    --2. sum()over(order by score asc)根据分组的score进行升序求和 select t.sno,t.cno,t.score, sum(score)over(order by score asc) as sum_num from sc t
      
        
       sum(score)over(order by score asc) as sum_num  这段代码其实我也不知道怎么说,
    第n行的SUM_NUM+第n行的SCORE=n+1行的SUM_NUM
      
    
    
    --3. sum(score)over(partition by cno order by score asc) 以cno 进行分区, 
    --然后按成绩升序进行求和
     select t.sno,t.cno,t.score, sum(score)over(partition by cno order by score asc) as sum_num from sc t

      
    
    

      

      五.总结

         其实分析函数的用法大同小异,我就不一一列举了,只能说我太懒,哈哈!不对的地方请各位大神多多指教!

  • 相关阅读:
    第四周:卷积神经网络 part3
    第四周作业:卷积神经网络学习part3
    视频学习--《 图像语义分割前沿进展》
    视频学习--《语义分割中的自注意力机制和低秩重建》
    第二次作业:卷积神经网络 part 1
    使用VGG模型迁移学习进行猫狗大战
    使用 VGG16 对 CIFAR10 分类
    CIFAR10 数据集分类
    MNIST数据集分类
    第一次作业:深度学习基础
  • 原文地址:https://www.cnblogs.com/SmallHan/p/6741163.html
Copyright © 2011-2022 走看看