recherche
Maisonbase de donnéestutoriel mysqloracle分析函数技术详解(配上开窗函数over())

一、Oracle分析函数入门 分析函数是什么? 分析函数是Oracle专门用于 解决复杂报表统计需求 的功能强大的函数, 它可以在数据中进行分组然后计算基于组的某种统计 ,并且每一组的每一行都可以返回一个统计。 分析函数和聚合函数的不同之处是什么? 普通的聚

一、Oracle分析函数入门

分析函数是什么?
分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值。

          

分析函数和聚合函数的不同之处是什么?
普通的聚合函数用group by分组,每个分组返回一个统计值,而分析函数采用partition by分组,并且每组每行都可以返回一个统计值。

              

分析函数的形式
分析函数带有一个开窗函数over(),包含三个分析子句:分组(partition by), 排序(order by), 窗口(rows) ,他们的使用形式如下:over(partition by xxx order by yyy rows between zzz)。
注:窗口子句在这里我只说rows方式的窗口,range方式和滑动窗口也不提

    

分析函数例子(在scott用户下模拟)

示例目的:显示各部门员工的工资,并附带显示该部分的最高工资。

oracle分析函数技术详解(配上开窗函数over())

<span>--</span><span>显示各部门员工的工资,并附带显示该部分的最高工资。</span><span>SELECT</span> E.DEPTNO,
       E.EMPNO,
       E.ENAME,
       E.SAL,
       LAST_VALUE(E.SAL) 
       <span>OVER</span>(PARTITION <span>BY</span> E.DEPTNO 
            <span>ORDER</span> <span>BY</span> E.SAL ROWS 
            <span>--</span><span>unbounded preceding and unbouned following针对当前所有记录的前一条、后一条记录,也就是表中的所有记录</span>            <span>--</span><span>unbounded:不受控制的,无限的</span>            <span>--</span><span>preceding:在...之前</span>            <span>--</span><span>following:在...之后</span>            <span>BETWEEN</span> UNBOUNDED PRECEDING <span>AND</span> UNBOUNDED FOLLOWING) MAX_SAL
  <span>FROM</span> EMP E;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

               

示例目的:按照deptno分组,然后计算每组值的总和

<span>SELECT</span> EMPNO,
       ENAME,
       DEPTNO,
       SAL,
       <span>SUM</span>(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO <span>ORDER</span> <span>BY</span> ENAME) max_sal
  <span>FROM</span> SCOTT.EMP;

运行结果:

oracle分析函数技术详解(配上开窗函数over())

     

示例目的:对各部门进行分组,并附带显示第一行至当前行的汇总

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> EMPNO,
       ENAME,
       DEPTNO,
       SAL,
       <span>--</span><span>注意ROWS BETWEEN unbounded preceding AND current row  是指第一行至当前行的汇总</span>       <span>SUM</span>(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO 
                     <span>ORDER</span> <span>BY</span> ENAME 
                     ROWS <span>BETWEEN</span> UNBOUNDED PRECEDING <span>AND</span> <span>CURRENT</span> ROW) max_sal
  <span>FROM</span> SCOTT.EMP;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

   

示例目标:当前行至最后一行的汇总

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> EMPNO,
       ENAME,
       DEPTNO,
       SAL,
       <span>--</span><span>注意ROWS BETWEEN current row AND unbounded following 指当前行到最后一行的汇总</span>       <span>SUM</span>(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO 
                     <span>ORDER</span> <span>BY</span> ENAME 
                     ROWS <span>BETWEEN</span> <span>CURRENT</span> ROW <span>AND</span> UNBOUNDED FOLLOWING) max_sal
  <span>FROM</span> SCOTT.EMP;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

   

 示例目标:当前行的上一行(rownum-1)到当前行的汇总

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> EMPNO,
       ENAME,
       DEPTNO,
       SAL,
       <span>--</span><span>注意ROWS BETWEEN 1 preceding AND current row 是指当前行的上一行(rownum-1)到当前行的汇总 </span>       <span>SUM</span>(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO 
                     <span>ORDER</span> <span>BY</span> ENAME ROWS 
                     <span>BETWEEN</span> <span>1</span> PRECEDING <span>AND</span> <span>CURRENT</span> ROW) max_sal
  <span>FROM</span> SCOTT.EMP;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

    

示例目标:   当前行的上一行(rownum-1)到当前行的下辆行(rownum+2)的汇总     

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> EMPNO,
       ENAME,
       DEPTNO,
       SAL,
       <span>--</span><span>注意ROWS BETWEEN 1 preceding AND 1 following 是指当前行的上一行(rownum-1)到当前行的下辆行(rownum+2)的汇总</span>       <span>SUM</span>(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO 
                     <span>ORDER</span> <span>BY</span> ENAME 
                     ROWS <span>BETWEEN</span> <span>1</span> PRECEDING <span>AND</span> <span>2</span> FOLLOWING) max_sal
  <span>FROM</span> SCOTT.EMP;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

     



二、理解over()函数

1.1、两个order by的执行时机
分析函数(以及与其配合的开窗函数over())是在整个sql查询结束后(sql语句中的order by的执行比较特殊)再进行的操作, 也就是说sql语句中的order by也会影响分析函数的执行结果:

a) 两者一致:如果sql语句中的order by满足分析函数配合的开窗函数over()分析时要求的排序,即sql语句中的order by子句里的内容和开窗函数over()中的order by子句里的内容一样,

那么sql语句中的排序将先执行,分析函数在分析时就不必再排序
b) 两者不一致:如果sql语句中的order by不满足分析函数配合的开窗函数over()分析时要求的排序,即sql语句中的order by子句里的内容和开窗函数over()中的order by子句里的内容不一样,

那么sql语句中的排序将最后在分析函数分析结束后执行排序

           

1.2、开窗函数over()分析函数中的分组/排序/窗口
      开窗函数over()分析函数包含三个分析子句:分组子句(partition by), 排序子句(order by), 窗口子句(rows)
      窗口就是分析函数分析时要处理的数据范围,就拿sum来说,它是sum窗口中的记录而不是整个分组中的记录,因此我们在想得到某个栏位的累计值时,我们需要把窗口指定到该分组中的第一行数据到当前行, 如果你指定该窗口从该分组中的第一行到最后一行,那么该组中的每一个sum值都会一样,即整个组的总和。

      窗口子句在这里我只说rows方式的窗口,range方式和滑动窗口也不提。


      窗口子句中我们经常用到指定第一行,当前行,最后一行这样的三个属性:
第一行是 unbounded preceding,
当前行是 current row,
最后一行是 unbounded following,

注释:

开窗函数over()出现分组(partition by)子句时,

unbounded preceding即第一行是指表中一个分组里的第一行, unbounded following最后一行是指表中一个分组里的最后一行

开窗函数over()省略了分组(partition by)子句时,

unbounded preceding即第一行是指表中的第一行, unbounded following最后一行是指表中的最后一行。


窗口子句不能单独出现,必须有order by子句时才能出现

例如:

<span>last_value(sal) <span>over</span>(partition <span>by</span> deptno 
                     <span>order</span> <span>by</span> sal 
                     rows <span>between</span> unbounded preceding <span>and</span> unbounded following)</span>

以上示例指定窗口为整个分组。而出现order by子句的时候,不一定要有窗口子句,但效果会很不一样,此时的窗口默认是当前组的第一行到当前行!


如果省略分组,则把全部记录当成一个组。
a) 如果存在order by则默认窗口是unbounded preceding and current row   --当前组的第一行到当前行
b) 如果这时省略order by则窗口默认为unbounded preceding and unbounded following  --整个组
 


而无论是否省略分组子句,如下结论都是成立的:

1、窗口子句不能单独出现,必须有order by子句时才能出现

2、当省略窗口子句时:
a) 如果存在order by则默认的窗口是unbounded preceding and current row  --当前组的第一行到当前行,即在当前组中,第一行到当前行
b) 如果同时省略order by则默认的窗口是unbounded preceding and unbounded following  --整个组

             
所以,

lag(sal) over(order by sal) 解释

over(order by salary)表示意义如下:

首先,我们要知道由于省略分组子句,所以当前组的范围为整个表的数据行,

然后,在当前组(此时为整个表的数据行)这个范围里执行排序(即order by salary),

最后,我们知道分析函数lag(sal)在当前组(此时为整个表的数据行)这个范围里的窗口范围为当前组的第一行到当前行,即分析函数lag(sal)在这个窗口范围执行。


参见:

Oracle的LAG和LEAD分析函数


Oracle分析函数ROW_NUMBER()|RANK()|LAG()使用详解


1.3、帮助理解over()的实例

例1:关注点:sql无排序,over()排序子句省略

<span>SELECT</span> DEPTNO, EMPNO, ENAME, SAL, 
       LAST_VALUE(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO)
<span>FROM</span> EMP;

运行结果:

 

oracle分析函数技术详解(配上开窗函数over())

       

例2:关注点:sql无排序,over()排序子句有,窗口省略

 

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> DEPTNO,
       EMPNO,
       ENAME,
       SAL,
       LAST_VALUE(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO 
                            <span>ORDER</span> <span>BY</span> SAL <span>DESC</span>)
  <span>FROM</span> EMP;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

 

oracle分析函数技术详解(配上开窗函数over())

                  
例3:关注点:sql无排序,over()排序子句有,窗口也有,窗口特意强调全组数据

 

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> DEPTNO,
       EMPNO,
       ENAME,
       SAL,
       LAST_VALUE(SAL) 
       <span>OVER</span>(PARTITION <span>BY</span> DEPTNO 
            <span>ORDER</span> <span>BY</span> SAL 
            ROWS <span>BETWEEN</span> UNBOUNDED PRECEDING <span>AND</span> UNBOUNDED FOLLOWING) MAX_SAL
  <span>FROM</span> EMP;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

 

oracle分析函数技术详解(配上开窗函数over())

     
例4:关注点:sql有排序(正序),over()排序子句无,先做sql排序再进行分析函数运算

 

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       LAST_VALUE(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO) LAST_VALUE
  <span>FROM</span> EMP
 <span>WHERE</span> DEPTNO <span>=</span> <span>30</span>
 <span>ORDER</span> <span>BY</span> DEPTNO, MGR;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

 

oracle分析函数技术详解(配上开窗函数over())

 



例5:关注点:sql有排序(倒序),over()排序子句无,先做sql排序再进行分析函数运算

 

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       LAST_VALUE(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO) LAST_VALUE
  <span>FROM</span> EMP
 <span>WHERE</span> DEPTNO <span>=</span> <span>30</span>
 <span>ORDER</span> <span>BY</span> DEPTNO, MGR <span>DESC</span>;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

                

例6:关注点:sql有排序(倒序),over()排序子句有,窗口子句无,此时的运算是:sql先选数据但是不排序,而后排序子句先排序并进行分析函数处理(窗口默认为第一行到当前行),最后再进行sql排序

 

 

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       <span>MIN</span>(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO <span>ORDER</span> <span>BY</span> SAL <span>ASC</span>) LAST_VALUE
  <span>FROM</span> EMP
 <span>WHERE</span> DEPTNO <span>=</span> <span>30</span>
 <span>ORDER</span> <span>BY</span> DEPTNO, MGR <span>DESC</span>;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

 

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       <span>MIN</span>(SAL) <span>OVER</span>(PARTITION <span>BY</span> DEPTNO <span>ORDER</span> <span>BY</span> SAL <span>DESC</span>) LAST_VALUE
  <span>FROM</span> EMP
 <span>WHERE</span> DEPTNO <span>=</span> <span>30</span>
 <span>ORDER</span> <span>BY</span> DEPTNO, MGR <span>DESC</span>;

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

              

三、常见分析函数详解

为了方便进行实践,特将演示表和数据罗列如下:

一、创建表

<span>create</span> <span>table</span> t( 
   bill_month <span>varchar2</span>(<span>12</span>) , 
   area_code <span>number</span>, 
   net_type <span>varchar</span>(<span>2</span>), 
   local_fare <span>number</span> 
);

      

二、插入数据

oracle分析函数技术详解(配上开窗函数over())

<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5761</span>,<span>'</span><span>G</span><span>'</span>, <span>7393344.04</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5761</span>,<span>'</span><span>J</span><span>'</span>, <span>5667089.85</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5762</span>,<span>'</span><span>G</span><span>'</span>, <span>6315075.96</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5762</span>,<span>'</span><span>J</span><span>'</span>, <span>6328716.15</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5763</span>,<span>'</span><span>G</span><span>'</span>, <span>8861742.59</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5763</span>,<span>'</span><span>J</span><span>'</span>, <span>7788036.32</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5764</span>,<span>'</span><span>G</span><span>'</span>, <span>6028670.45</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5764</span>,<span>'</span><span>J</span><span>'</span>, <span>6459121.49</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5765</span>,<span>'</span><span>G</span><span>'</span>, <span>13156065.77</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200405</span><span>'</span>,<span>5765</span>,<span>'</span><span>J</span><span>'</span>, <span>11901671.70</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5761</span>,<span>'</span><span>G</span><span>'</span>, <span>7614587.96</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5761</span>,<span>'</span><span>J</span><span>'</span>, <span>5704343.05</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5762</span>,<span>'</span><span>G</span><span>'</span>, <span>6556992.60</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5762</span>,<span>'</span><span>J</span><span>'</span>, <span>6238068.05</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5763</span>,<span>'</span><span>G</span><span>'</span>, <span>9130055.46</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5763</span>,<span>'</span><span>J</span><span>'</span>, <span>7990460.25</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5764</span>,<span>'</span><span>G</span><span>'</span>, <span>6387706.01</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5764</span>,<span>'</span><span>J</span><span>'</span>, <span>6907481.66</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5765</span>,<span>'</span><span>G</span><span>'</span>, <span>13562968.81</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200406</span><span>'</span>,<span>5765</span>,<span>'</span><span>J</span><span>'</span>, <span>12495492.50</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5761</span>,<span>'</span><span>G</span><span>'</span>, <span>7987050.65</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5761</span>,<span>'</span><span>J</span><span>'</span>, <span>5723215.28</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5762</span>,<span>'</span><span>G</span><span>'</span>, <span>6833096.68</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5762</span>,<span>'</span><span>J</span><span>'</span>, <span>6391201.44</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5763</span>,<span>'</span><span>G</span><span>'</span>, <span>9410815.91</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5763</span>,<span>'</span><span>J</span><span>'</span>, <span>8076677.41</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5764</span>,<span>'</span><span>G</span><span>'</span>, <span>6456433.23</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5764</span>,<span>'</span><span>J</span><span>'</span>, <span>6987660.53</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5765</span>,<span>'</span><span>G</span><span>'</span>, <span>14000101.20</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200407</span><span>'</span>,<span>5765</span>,<span>'</span><span>J</span><span>'</span>, <span>12301780.20</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5761</span>,<span>'</span><span>G</span><span>'</span>, <span>8085170.84</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5761</span>,<span>'</span><span>J</span><span>'</span>, <span>6050611.37</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5762</span>,<span>'</span><span>G</span><span>'</span>, <span>6854584.22</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5762</span>,<span>'</span><span>J</span><span>'</span>, <span>6521884.50</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5763</span>,<span>'</span><span>G</span><span>'</span>, <span>9468707.65</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5763</span>,<span>'</span><span>J</span><span>'</span>, <span>8460049.43</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5764</span>,<span>'</span><span>G</span><span>'</span>, <span>6587559.23</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5764</span>,<span>'</span><span>J</span><span>'</span>, <span>7342135.86</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5765</span>,<span>'</span><span>G</span><span>'</span>, <span>14450586.63</span>); 
<span>insert</span> <span>into</span> t <span>values</span>(<span>'</span><span>200408</span><span>'</span>,<span>5765</span>,<span>'</span><span>J</span><span>'</span>, <span>12680052.38</span>); 
<span>commit</span>;

oracle分析函数技术详解(配上开窗函数over())

            

三、first_value()与last_value():求最值对应的其他属性
问题、取出每月通话费最高和最低的两个地区。

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> BILL_MONTH, 
       AREA_CODE,
       <span>SUM</span>(LOCAL_FARE) LOCAL_FARE, 
       FIRST_VALUE(AREA_CODE) 
       <span>OVER</span>(PARTITION <span>BY</span> BILL_MONTH 
            <span>ORDER</span> <span>BY</span> <span>SUM</span>(LOCAL_FARE) <span>DESC</span> 
            ROWS <span>BETWEEN</span> UNBOUNDED PRECEDING <span>AND</span> UNBOUNDED FOLLOWING) FIRSTVAL, 
       LAST_VALUE(AREA_CODE) 
       <span>OVER</span>(PARTITION <span>BY</span> BILL_MONTH 
            <span>ORDER</span> <span>BY</span> <span>SUM</span>(LOCAL_FARE) <span>DESC</span> 
            ROWS <span>BETWEEN</span> UNBOUNDED PRECEDING <span>AND</span> UNBOUNDED FOLLOWING) LASTVAL 
  <span>FROM</span> T 
 <span>GROUP</span> <span>BY</span> BILL_MONTH, AREA_CODE 
 <span>ORDER</span> <span>BY</span> BILL_MONTH

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

   

四、rank(),dense_rank()与row_number():求排序

rank,dense_rank,row_number函数为每条记录产生一个从1开始至n的自然数,n的值可能小于等于记录的总数。这3个函数的唯一区别在于当碰到相同数据时的排名策略
①row_number:
row_number函数返回一个唯一的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增
②dense_rank:
dense_rank函数返回一个唯一的值,当碰到相同数据时,此时所有相同数据的排名都是一样的
③rank:
rank函数返回一个唯一的值,当碰到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名

          

演示数据在Oracle自带的scott用户下:
1、rank()值相同时排名相同,其后排名跳跃不连续

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> <span>*</span> 
  <span>FROM</span> (<span>SELECT</span> DEPTNO, 
               RANK() <span>OVER</span>(PARTITION <span>BY</span> DEPTNO <span>ORDER</span> <span>BY</span> SAL <span>DESC</span>) RW, 
               ENAME,
               SAL
          <span>FROM</span> SCOTT.EMP) 
 <span>WHERE</span> RW <span> <span>4</span>;</span>

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())
2、dense_rank()值相同时排名相同,其后排名连续不跳跃

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> <span>*</span> 
  <span>FROM</span> (<span>SELECT</span> DEPTNO, 
               DENSE_RANK() <span>OVER</span>(PARTITION <span>BY</span> DEPTNO <span>ORDER</span> <span>BY</span> SAL <span>DESC</span>) RW, 
               ENAME,
               SAL
          <span>FROM</span> SCOTT.EMP) 
 <span>WHERE</span> RW <span> <span>4</span>;</span>

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())
3、row_number()值相同时排名不相等,其后排名连续不跳跃

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> <span>*</span> 
  <span>FROM</span> (<span>SELECT</span> DEPTNO, 
               ROW_NUMBER() <span>OVER</span>(PARTITION <span>BY</span> DEPTNO <span>ORDER</span> <span>BY</span> SAL <span>DESC</span>) RW, 
               ENAME,
               SAL
          <span>FROM</span> SCOTT.EMP) 
 <span>WHERE</span> RW <span> <span>4</span>;</span>

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

 

五、lag()与lead():求之前或之后的第N行
lag和lead函数可以在一次查询中取出同一字段的前n行的数据和后n行的值。这种操作可以使用对相同表的表连接来实现,不过使用lag和lead有更高的效率。
lag(arg1,arg2,arg3)
第一个参数是列名,
第二个参数是偏移的offset,
第三个参数是超出记录窗口时的默认值。
  
举例如下:
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> 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> select id,name,lead(name,1,'linjiqin') 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                linjiqin  

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

   

六、rollup()与cube():排列组合分组
1)、group by rollup(a, b, c):
首先会对(a、b、c)进行group by,
然后再对(a、b)进行group by,
其后再对(a)进行group by,
最后对全表进行汇总操作。

     

2)、group by cube(a, b, c):
则首先会对(a、b、c)进行group by,
然后依次是(a、b),(a、c),(a),(b、c),(b),(c),
最后对全表进行汇总操作。

   

1、生成演示数据:
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as ds_trade
 
SQL> conn system/oracle as sysdba
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as SYS
 
SQL> create table scott.t as select * from dba_indexes;
 
Table created
 
 
SQL> connect scott/oracle
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as scott
 
SQL>

    

2、普通group by体验
sql> select owner, index_type, status, count(*) from t where owner like 'SY%' group by owner, index_type, status;

oracle分析函数技术详解(配上开窗函数over())

3、group by rollup(A,B,C)
GROUP BY ROLLUP(A, B, C):
首先会对(A、B、C)进行GROUP BY,
然后再对(A、B)进行GROUP BY,
其后再对(A)进行GROUP BY,
最后对全表进行汇总操作。
sql> select owner, index_type, status, count(*) from t where owner like 'SY%' group by ROLLUP(owner, index_type, status);

oracle分析函数技术详解(配上开窗函数over())

4、group by cube(A,B,C)
GROUP BY CUBE(A, B, C):
则首先会对(A、B、C)进行GROUP BY,
然后依次是(A、B),(A、C),(A),(B、C),(B),(C),
最后对全表进行汇总操作。

sql> select owner, index_type, status, count(*) from t where owner like 'SY%' group by cube(owner, index_type, status);

oracle分析函数技术详解(配上开窗函数over())

  

七、max(),min(),sun()与avg():求移动的最值总和与平均值
问题:计算出各个地区连续3个月的通话费用的平均数(移动平均值)

 

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> AREA_CODE, 
       BILL_MONTH,
       LOCAL_FARE,
       <span>SUM</span>(LOCAL_FARE) <span>OVER</span>(PARTITION <span>BY</span> AREA_CODE 
                            <span>ORDER</span> <span>BY</span> TO_NUMBER(BILL_MONTH) 
                            RANGE <span>BETWEEN</span> <span>1</span> PRECEDING <span>AND</span> <span>1</span> FOLLOWING) "3month_sum", 
       <span>AVG</span>(LOCAL_FARE) <span>OVER</span>(PARTITION <span>BY</span> AREA_CODE 
                            <span>ORDER</span> <span>BY</span> TO_NUMBER(BILL_MONTH) 
                            RANGE <span>BETWEEN</span> <span>1</span> PRECEDING <span>AND</span> <span>1</span> FOLLOWING) "3month_avg", 
       <span>MAX</span>(LOCAL_FARE) <span>OVER</span>(PARTITION <span>BY</span> AREA_CODE 
                            <span>ORDER</span> <span>BY</span> TO_NUMBER(BILL_MONTH) 
                            RANGE <span>BETWEEN</span> <span>1</span> PRECEDING <span>AND</span> <span>1</span> FOLLOWING) "3month_max", 
       <span>MIN</span>(LOCAL_FARE) <span>OVER</span>(PARTITION <span>BY</span> AREA_CODE 
                            <span>ORDER</span> <span>BY</span> TO_NUMBER(BILL_MONTH) 
                            RANGE <span>BETWEEN</span> <span>1</span> PRECEDING <span>AND</span> <span>1</span> FOLLOWING) "3month_min" 
  <span>FROM</span> (<span>SELECT</span> T.AREA_CODE, T.BILL_MONTH, <span>SUM</span>(T.LOCAL_FARE) LOCAL_FARE 
          <span>FROM</span> T 
         <span>GROUP</span> <span>BY</span> T.AREA_CODE, T.BILL_MONTH)

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

  

问题:求各地区按月份累加的通话费

oracle分析函数技术详解(配上开窗函数over())

<span>SELECT</span> AREA_CODE, 
       BILL_MONTH,
       LOCAL_FARE,
       <span>SUM</span>(LOCAL_FARE) <span>OVER</span>(PARTITION <span>BY</span> AREA_CODE 
                            <span>ORDER</span> <span>BY</span> BILL_MONTH <span>ASC</span>) "last_sum_value" 
  <span>FROM</span> (<span>SELECT</span> T.AREA_CODE, T.BILL_MONTH, <span>SUM</span>(T.LOCAL_FARE) LOCAL_FARE 
          <span>FROM</span> T 
         <span>GROUP</span> <span>BY</span> T.AREA_CODE, T.BILL_MONTH) 
 <span>ORDER</span> <span>BY</span> AREA_CODE, BILL_MONTH

oracle分析函数技术详解(配上开窗函数over())

运行结果:

oracle分析函数技术详解(配上开窗函数over())

 

--------------------------------------------------------------------------
Blog:http://www.cnblogs.com/linjiqin/
J2EE、Android、Linux、Oracle QQ交流群:142463980、158560018(满)

另见:《Oracle分析函数ROW_NUMBER()|RANK()|LAG()使用详解

Déclaration
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
MySQL: Compétences essentielles pour les débutants à maîtriserMySQL: Compétences essentielles pour les débutants à maîtriserApr 18, 2025 am 12:24 AM

MySQL convient aux débutants pour acquérir des compétences de base de données. 1. Installez les outils MySQL Server et Client. 2. Comprendre les requêtes SQL de base, telles que SELECT. 3. 掌握数据操作: : 创建表、插入、更新、删除数据。 4. 学习高级技巧: : 子查询和窗口函数。 5. 调试和优化: : 检查语法、使用索引、避免 Sélectionner * , 并使用 Limite。

MySQL: données structurées et bases de données relationnellesMySQL: données structurées et bases de données relationnellesApr 18, 2025 am 12:22 AM

MySQL gère efficacement les données structurées par la structure de la table et la requête SQL, et met en œuvre des relations inter-tableaux à travers des clés étrangères. 1. Définissez le format de données et tapez lors de la création d'une table. 2. Utilisez des clés étrangères pour établir des relations entre les tables. 3. Améliorer les performances par l'indexation et l'optimisation des requêtes. 4. Bases de données régulièrement sauvegarde et surveillent régulièrement la sécurité des données et l'optimisation des performances.

MySQL: fonctionnalités et capacités clés expliquésMySQL: fonctionnalités et capacités clés expliquésApr 18, 2025 am 12:17 AM

MySQL est un système de gestion de base de données relationnel open source qui est largement utilisé dans le développement Web. Ses caractéristiques clés incluent: 1. Prend en charge plusieurs moteurs de stockage, tels que InNODB et Myisam, adaptés à différents scénarios; 2. Fournit des fonctions de réplication à esclave maître pour faciliter l'équilibrage de la charge et la sauvegarde des données; 3. Améliorez l'efficacité de la requête grâce à l'optimisation des requêtes et à l'utilisation d'index.

Le but de SQL: interagir avec les bases de données MySQLLe but de SQL: interagir avec les bases de données MySQLApr 18, 2025 am 12:12 AM

SQL est utilisé pour interagir avec la base de données MySQL pour réaliser l'ajout de données, la suppression, la modification, l'inspection et la conception de la base de données. 1) SQL effectue des opérations de données via des instructions SELECT, INSERT, UPDATE, DELETE; 2) Utiliser des instructions Create, Alter, Drop pour la conception et la gestion de la base de données; 3) Les requêtes complexes et l'analyse des données sont mises en œuvre via SQL pour améliorer l'efficacité de la prise de décision commerciale.

MySQL pour les débutants: commencer la gestion de la base de donnéesMySQL pour les débutants: commencer la gestion de la base de donnéesApr 18, 2025 am 12:10 AM

Les opérations de base de MySQL incluent la création de bases de données, les tables et l'utilisation de SQL pour effectuer des opérations CRUD sur les données. 1. Créez une base de données: CreatedAtAbaseMy_First_DB; 2. Créez un tableau: CreateTableBooks (idIntauto_inCmentPrimaryKey, TitleVarchar (100) notnull, AuthorVarchar (100) notnull, publied_yearint); 3. Données d'insertion: INSERTINTOBOOKS (titre, auteur, publié_year) VA

Rôle de MySQL: Bases de données dans les applications WebRôle de MySQL: Bases de données dans les applications WebApr 17, 2025 am 12:23 AM

Le rôle principal de MySQL dans les applications Web est de stocker et de gérer les données. 1.MySQL traite efficacement les informations utilisateur, les catalogues de produits, les enregistrements de transaction et autres données. 2. Grâce à SQL Query, les développeurs peuvent extraire des informations de la base de données pour générer du contenu dynamique. 3.MySQL fonctionne basé sur le modèle client-serveur pour assurer une vitesse de requête acceptable.

MySQL: Construire votre première base de donnéesMySQL: Construire votre première base de donnéesApr 17, 2025 am 12:22 AM

Les étapes pour construire une base de données MySQL incluent: 1. Créez une base de données et une table, 2. Insérer des données et 3. Conduisez des requêtes. Tout d'abord, utilisez les instructions CreateDatabase et CreateTable pour créer la base de données et la table, puis utilisez l'instruction InsertInto pour insérer les données, et enfin utilisez l'instruction SELECT pour interroger les données.

MySQL: une approche adaptée aux débutants du stockage de donnéesMySQL: une approche adaptée aux débutants du stockage de donnéesApr 17, 2025 am 12:21 AM

MySQL convient aux débutants car il est facile à utiliser et puissant. 1.MySQL est une base de données relationnelle et utilise SQL pour les opérations CRUD. 2. Il est simple à installer et nécessite la configuration du mot de passe de l'utilisateur racine. 3. Utilisez l'insertion, la mise à jour, la suppression et la sélection pour effectuer des opérations de données. 4. OrderBy, où et jointure peut être utilisé pour des requêtes complexes. 5. Le débogage nécessite de vérifier la syntaxe et d'utiliser Expliquez pour analyser la requête. 6. Les suggestions d'optimisation incluent l'utilisation d'index, le choix du bon type de données et de bonnes habitudes de programmation.

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Vous avez un jeu croisé?
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Listes Sec

Listes Sec

SecLists est le compagnon ultime du testeur de sécurité. Il s'agit d'une collection de différents types de listes fréquemment utilisées lors des évaluations de sécurité, le tout en un seul endroit. SecLists contribue à rendre les tests de sécurité plus efficaces et productifs en fournissant facilement toutes les listes dont un testeur de sécurité pourrait avoir besoin. Les types de listes incluent les noms d'utilisateur, les mots de passe, les URL, les charges utiles floues, les modèles de données sensibles, les shells Web, etc. Le testeur peut simplement extraire ce référentiel sur une nouvelle machine de test et il aura accès à tous les types de listes dont il a besoin.

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Télécharger la version Mac de l'éditeur Atom

Télécharger la version Mac de l'éditeur Atom

L'éditeur open source le plus populaire

MinGW - GNU minimaliste pour Windows

MinGW - GNU minimaliste pour Windows

Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.