oracle之分析函數sum()over()


分析函數語法:

FUNCTION_NAME(<argument>,<argument>...)
OVER
(<Partition-Clause><Order-by-Clause><Windowing Clause>)

例:

sum(sal) over (partition by deptno order by ename) new_alias

解析:

sum就是函數名;(sal)是分析函數的參數,每個函數有0~3個參數,參數可以是表達式,例如:sum(sal+comm);over 是一個關鍵字,用於標識分析函數,否則查詢分析器不能區別sum()聚集函數和sum()分析函數;partition by deptno 是可選的分區子句,如果不存在任何分區子句,則全部的結果集可看作一個單一的大區;order by ename 是可選的order by 子句,有些函數需要它,有些則不需要

測試:

  建表:

-- Create table
create table SCOTT.T_TEST_ORDER
(
cust_nbr NUMBER,
region_id NUMBER,
salesperson_id NUMBER,
year NUMBER,
month NUMBER,
tot_orders NUMBER,
tot_sales NUMBER
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);

  插入數據: 

      11          7             11                       2001          7          2      12204
          4          5              4                         2001         10         2      37802
          7          6              7                         2001          2          3       3750
         10          6              8                        2001          1          2      21691
         10          6              7                        2001          2          3      42624
         15          7             12                       2000          5          6         24
         12          7              9                        2000          6          2      50658
          1          5              2                         2000          3          2      44494
          1          5              1                         2000          9          2      74864
          2          5              4                         2000          3          2      35060
          2          5              4                         2000          4          4       6454
          2          5              1                         2000         10          4      35580
          4          5              4                         2000         12          2      39190

  查詢:

select cust_nbr,region_id,
sum(tot_sales),
sum(sum(tot_sales)) over(partition by region_id)
from scott.t_test_order
--where year = 2001
group by region_id, cust_nbr;

  分析一下:首先,以region_id ,cust_nbr 這倆字段組合分組,計算出每組 tot_sales 的和,然后又以 region_id 作為分組條件,在原來求和的基礎上又進行求和,得到最終數據(這個思路值得借鑒)。

請注意上面的綠色高亮部分,group by的意圖很明顯:將數據按區域ID,客戶進行分組,那么Over這一部分有什么用呢?假如我們只需要統計每個區域每個客戶的訂單總額,那么我們只需要group by o.region_id,o.cust_nbr就夠了。但我們還想在每一行顯示該客戶所在區域的訂單總額,這一點和前面的不同:需要在前面分組的基礎上按區域累加。很顯然group by和sum是無法做到這一點的(因為聚集操作的級別不一樣,前者是對一個客戶,后者是對一批客戶)。這就是over函數的作用了!它的作用是告訴SQL引擎:按區域對數據進行分區,然后累積每個區域每個客戶的訂單總額(sum(sum(o.tot_sales)))。

 上面的sql統計分析了 每個客戶及其對應區域的訂單總額

下面篩選那些個客戶訂單總額占到區域訂單總額20%以上

select * from 
(
select cust_nbr,region_id,
sum(tot_sales) a ,
sum(sum(tot_sales)) over(partition by region_id) b
from scott.t_test_order
--where year = 2001
group by region_id, cust_nbr
)a_t 
where a_t.a>a_t.b*0.2;

 如果我們想要知道每個大客戶所占的訂單比例呢?

select a_t.*,round(a_t.a/a_t.b,2)*100||'%' precend from 
(
select cust_nbr,region_id,
sum(tot_sales) a ,
sum(sum(tot_sales)) over(partition by region_id) b
from scott.t_test_order
--where year = 2001
group by region_id, cust_nbr
)a_t 
where a_t.a>a_t.b*0.2;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM