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;

 

猜你喜欢

转载自www.cnblogs.com/wuyuchuan/p/12572690.html