分析函数语法:
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;
原文:https://www.cnblogs.com/wuyuchuan/p/12572690.html