検索
ホームページデータベースmysql チュートリアルoracle分析函数技术详解(配上开窗函数over())

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

Jun 07, 2016 pm 03:50 PM
oracleover関数分析するテクノロジー詳しい説明

一、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()使用详解

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
MySQL:世界で最も人気のあるデータベースの紹介MySQL:世界で最も人気のあるデータベースの紹介Apr 12, 2025 am 12:18 AM

MySQLはオープンソースのリレーショナルデータベース管理システムであり、主にデータを迅速かつ確実に保存および取得するために使用されます。その実用的な原則には、クライアントリクエスト、クエリ解像度、クエリの実行、返品結果が含まれます。使用法の例には、テーブルの作成、データの挿入とクエリ、および参加操作などの高度な機能が含まれます。一般的なエラーには、SQL構文、データ型、およびアクセス許可、および最適化の提案には、インデックスの使用、最適化されたクエリ、およびテーブルの分割が含まれます。

MySQLの重要性:データストレージと管理MySQLの重要性:データストレージと管理Apr 12, 2025 am 12:18 AM

MySQLは、データストレージ、管理、クエリ、セキュリティに適したオープンソースのリレーショナルデータベース管理システムです。 1.さまざまなオペレーティングシステムをサポートし、Webアプリケーションやその他のフィールドで広く使用されています。 2。クライアントサーバーアーキテクチャとさまざまなストレージエンジンを通じて、MySQLはデータを効率的に処理します。 3.基本的な使用には、データベースとテーブルの作成、挿入、クエリ、データの更新が含まれます。 4.高度な使用には、複雑なクエリとストアドプロシージャが含まれます。 5.一般的なエラーは、説明ステートメントを介してデバッグできます。 6.パフォーマンスの最適化には、インデックスの合理的な使用と最適化されたクエリステートメントが含まれます。

なぜMySQLを使用するのですか?利点と利点なぜMySQLを使用するのですか?利点と利点Apr 12, 2025 am 12:17 AM

MySQLは、そのパフォーマンス、信頼性、使いやすさ、コミュニティサポートに選択されています。 1.MYSQLは、複数のデータ型と高度なクエリ操作をサポートし、効率的なデータストレージおよび検索機能を提供します。 2.クライアントサーバーアーキテクチャと複数のストレージエンジンを採用して、トランザクションとクエリの最適化をサポートします。 3.使いやすく、さまざまなオペレーティングシステムとプログラミング言語をサポートしています。 4.強力なコミュニティサポートを提供し、豊富なリソースとソリューションを提供します。

InnoDBロックメカニズム(共有ロック、排他的ロック、意図ロック、レコードロック、ギャップロック、次のキーロック)を説明します。InnoDBロックメカニズム(共有ロック、排他的ロック、意図ロック、レコードロック、ギャップロック、次のキーロック)を説明します。Apr 12, 2025 am 12:16 AM

INNODBのロックメカニズムには、共有ロック、排他的ロック、意図ロック、レコードロック、ギャップロック、次のキーロックが含まれます。 1.共有ロックにより、トランザクションは他のトランザクションが読み取らないようにデータを読み取ることができます。 2.排他的ロックは、他のトランザクションがデータの読み取りと変更を防ぎます。 3.意図ロックは、ロック効率を最適化します。 4。ロックロックインデックスのレコードを記録します。 5。ギャップロックロックインデックス記録ギャップ。 6.次のキーロックは、データの一貫性を確保するためのレコードロックとギャップロックの組み合わせです。

貧弱なMySQLクエリパフォーマンスの一般的な原因は何ですか?貧弱なMySQLクエリパフォーマンスの一般的な原因は何ですか?Apr 12, 2025 am 12:11 AM

MySQLクエリのパフォーマンスが低いことの主な理由には、インデックスの使用、クエリオプティマイザーによる誤った実行計画の選択、不合理なテーブルデザイン、過剰なデータボリューム、ロック競争などがあります。 1.インデックスがゆっくりとクエリを引き起こし、インデックスを追加するとパフォーマンスが大幅に向上する可能性があります。 2。説明コマンドを使用してクエリ計画を分析し、オプティマイザーエラーを見つけます。 3.テーブル構造の再構築と結合条件を最適化すると、テーブルの設計上の問題が改善されます。 4.データボリュームが大きい場合、パーティション化とテーブル分割戦略が採用されます。 5.高い並行性環境では、トランザクションの最適化とロック戦略は、ロック競争を減らすことができます。

複数の単一列インデックスに対して複合インデックスをいつ使用する必要がありますか?複数の単一列インデックスに対して複合インデックスをいつ使用する必要がありますか?Apr 11, 2025 am 12:06 AM

データベースの最適化では、クエリ要件に従ってインデックス作成戦略を選択する必要があります。1。クエリに複数の列が含まれ、条件の順序が固定されている場合、複合インデックスを使用します。 2。クエリに複数の列が含まれているが、条件の順序が修正されていない場合、複数の単一列インデックスを使用します。複合インデックスは、マルチコラムクエリの最適化に適していますが、単一列インデックスは単一列クエリに適しています。

MySQLでスロークエリを識別して最適化する方法は? (スロークエリログ、Performance_schema)MySQLでスロークエリを識別して最適化する方法は? (スロークエリログ、Performance_schema)Apr 10, 2025 am 09:36 AM

MySQLスロークエリを最適化するには、slowquerylogとperformance_schemaを使用する必要があります。1。LowerQueryLogを有効にし、しきい値を設定して、スロークエリを記録します。 2。performance_schemaを使用してクエリの実行の詳細を分析し、パフォーマンスのボトルネックを見つけて最適化します。

MySQLおよびSQL:開発者にとって不可欠なスキルMySQLおよびSQL:開発者にとって不可欠なスキルApr 10, 2025 am 09:30 AM

MySQLとSQLは、開発者にとって不可欠なスキルです。 1.MYSQLはオープンソースのリレーショナルデータベース管理システムであり、SQLはデータベースの管理と操作に使用される標準言語です。 2.MYSQLは、効率的なデータストレージと検索機能を介して複数のストレージエンジンをサポートし、SQLは簡単なステートメントを通じて複雑なデータ操作を完了します。 3.使用の例には、条件によるフィルタリングやソートなどの基本的なクエリと高度なクエリが含まれます。 4.一般的なエラーには、SQLステートメントをチェックして説明コマンドを使用することで最適化できる構文エラーとパフォーマンスの問題が含まれます。 5.パフォーマンス最適化手法には、インデックスの使用、フルテーブルスキャンの回避、参加操作の最適化、コードの読み取り可能性の向上が含まれます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。