oracle over()函数及ratio_to_report()函数学习

今儿要用到一个统计查询,自己写了个,给经理一看,say No,子查询太多,影响效率,下午扔给了我一个sql,顿时懵了,啥玩意啊,没见过,好吧,百度一下,哈哈

SELECT A.EVALUATION,
       COUNT(A.REC_ID),
       RATIO_TO_REPORT(COUNT(A.REC_ID)) OVER()
  FROM ECM_ORDER_GOODS A, ECM_ORDER B
 WHERE A.ORDER_ID = B.ORDER_ID
   AND B.STORE_ID = '1'
 GROUP BY A.EVALUATION

先把sql贴出来,再慢慢研究哈。。


主要涉及到2个函数,主要理解ver()函数

        一般是在做统计的时候与统计函数一块使用,官方的解释没找到,贴两个例子(来源网络),自己慢慢读理解,你们感受一下

SQL> break on '' -- 取消数据分段显示
SQL> select deptno,ename,sal,
2 sum(sal) over (order by ename) 连续求和,
3 sum(sal) over () 总和,             -- 此处sum(sal) over () 等同于sum(sal)

4 100*round(sal/sum(sal) over (),4) "份额(%)" --同上
5 from emp
6 /

    DEPTNO ENAME             SAL   连续求和       总和    份额(%)
---------- ---------- ---------- ---------- ---------- ----------
        20 ADAMS            1100       1100      29025       3.79
        30 ALLEN            1600       2700      29025       5.51
        30 BLAKE            2850       5550      29025       9.82
        10 CLARK            2450       8000      29025       8.44
        20 FORD             3000      11000      29025      10.34
        30 JAMES             950      11950      29025       3.27
        20 JONES            2975      14925      29025      10.25
        10 KING             5000      19925      29025      17.23
        30 MARTIN           1250      21175      29025       4.31
        10 MILLER           1300      22475      29025       4.48
        20 SCOTT            3000      25475      29025      10.34
        20 SMITH             800      26275      29025       2.76
        30 TURNER           1500      27775      29025       5.17
        30 WARD             1250      29025      29025       4.31

已选择14行。

主要对比 “连续求和” 和 “总和” 两列 !

下面还有一个例子,你们再感受一下

SQL> select deptno,ename,sal,
2 sum(sal) over (partition by deptno order by ename) 部门连续求和,--各部门的薪水"连续"求和
3 sum(sal) over (partition by deptno) 部门总和, -- 部门统计的总和,同一部门总和不变
4 100*round(sal/sum(sal) over (partition by deptno),4) "部门份额(%)",
5 sum(sal) over (order by deptno,ename) 连续求和, --所有部门的薪水"连续"求和
6 sum(sal) over () 总和, -- 此处sum(sal) over () 等同于sum(sal),所有员工的薪水总和

7 100*round(sal/sum(sal) over (),4) "总份额(%)"
8 from emp
9 /

DEPTNO ENAME    SAL 部门连续求和   部门总和 部门份额(%)   连续求和   总和 总份额(%)
------ ------ ----- ------------ ---------- ----------- ---------- ------ ----------
    10 CLARK   2450         2450       8750          28       2450   29025       8.44
           KING    5000         7450       8750       57.14       7450   29025      17.23
       MILLER    1300         8750       8750       14.86       8750   29025       4.48

    20 ADAMS   1100         1100     10875       10.11       9850   29025       3.79
          FORD    3000         4100      10875       27.59      12850   29025      10.34
         JONES   2975         7075      10875       27.36      15825   29025      10.25
         SCOTT   3000        10075      10875       27.59      18825   29025      10.34
          SMITH    800        10875      10875        7.36      19625   29025       2.76

    30 ALLEN   1600         1600       9400       17.02      21225   29025       5.51
       BLAKE   2850         4450       9400       30.32      24075   29025       9.82
       JAMES    950         5400       9400       10.11      25025   29025       3.27
       MARTIN 1250         6650       9400        13.3      26275   29025       4.31
       TURNER 1500         8150       9400       15.96      27775   29025       5.17
       WARD    1250         9400       9400        13.3      29025   29025       4.31


已选择14行。

主要对比 部门连续求和” 与 “部门总和” 以及 “连续求和” 与 “总和”  以及  “部门份额” 和 "总份额" 之间的关系,主要在于over()函数里面order bypartition by的使用

有order by的就是连续求和。当然partition by是用来分组显示!最外层的循环order by不能随便加,在里面用partition by分组就可以,当然分组规则一样也行!

 

 

RATIO_TO_REPORT

 

Oracl 8i中引入的该函数,格式如下:
RATIO_TO_REPORT (expr) OVER(query_partition_clause)
Oracle计算百分比的方法是在总计报告的子查询中使用SUM函数总计报告,然后把那个结果放到细节表中相除来计算百分比。你还可以用一个子查询作为SELECT语句表达式:
RATIO_TO_REPORT解析函数使得这种类型的查询更容易编码。

 

还是贴两个网上的实例,大家一块感受一下

 

SELECT
   sales_rep_id, customer_id, order_total,
   ratio_to_report(order_total) OVER () pct_total
FROM
   orders
WHERE
   sales_rep_id = 163
ORDER BY
   sales_rep_id, customer_id, order_id
/
 
SQL> @ratioreport_a
 
SALES_REP_ID CUSTOMER_ID ORDER_TOTAL  PCT_TOTAL                                 
------------ ----------- ----------- ----------                                 
         163         102      5610.6 .043747539                                 
         163         102       10523 .082051002                                 
         163         103          78  .00060819                                 
         163         103       13550 .105653433                                 
         163         105      1926.6 .015022281                                 
         163         106      5546.6 .043248512                                 
         163         117      3878.4 .030241054                                 
         163         147      1500.8  .01170219                                 
         163         149        9055 .070604564                                 
         163         156       68501  .53412294                                 
         163         157      7110.3 .055441152                                 
         163         160       969.2 .007557144                                 
 
12 rows selected.
 
SQL>

 

col order_total format 999,999.00

 

col pct_total format 999.00
 
SELECT
   sales_rep_id, 
   customer_id, 
   order_total,
   ROUND(100*ratio_to_report(order_total) 
      OVER (PARTITION BY customer_id),2) pct_total --注意上面讲到的over()函数的用法,以customer_id分组
FROM
   orders
WHERE
   sales_rep_id = 163
ORDER BY
   sales_rep_id, customer_id, order_id/
 
SQL> @ratioreport_b
 
SALES_REP_ID CUSTOMER_ID ORDER_TOTAL PCT_TOTAL                                  
------------ ----------- ----------- ---------                                  
         163         102    5,610.60     34.78                                  
         163         102   10,523.00     65.22                                  
         163         103       78.00       .57                                  
         163         103   13,550.00     99.43                                  
         163         105    1,926.60    100.00                                  
         163         106    5,546.60    100.00                                  
         163         117    3,878.40    100.00                                  
         163         147    1,500.80    100.00                                  
         163         149    9,055.00    100.00                                  
         163         156   68,501.00    100.00                                  
         163         157    7,110.30    100.00                                  
         163         160      969.20    100.00                                  
 
12 rows selected.
 
SQL> spool off

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值