SELECT CUST_NBR,REGION_ID,YEAR, SUM(TOT_SALES) AS CUST_TOT,
SUM(SUM(TOT_SALES)) OVER(PARTITION BY REGION_ID,YEAR ORDER BY YEAR,REGION_ID) AS REGION_TOT
FROM ORDERS_TMP
GROUP BY REGION_ID,YEAR,CUST_NBR
ORDER BY YEAR,REGION_ID,CUST_NBR
这上面代码中有个问题,为什么要 SUM(SUM(TOT_SALES)),我认为over语句已经重新定义分组了,那么SUM(TOT_SALES) 就可以把region_id, year各个分组的情况计算出来了,如果不加,提示ORA_00979的错误,为什么啊?
解决方案 »
- PLS-00553: character set name is not recognized 字符集的问题
- 关于一句PLSQL文,没看懂,求大神解释,谢谢啦,都来看看
- ORacle imp 时产生问题 急求帮助,请大家看看为什么CMS_CONTENTS导不进去
- 请问关于统计查询的问题
- oci连接数据库,编译后出现 undefined reference to `OCIInitialize' 是什么意思?哪位高手会?
- 在Oracle中如何根据记录行来转变为记录列
- 超级简单问题
- 高手救命!!树型查询
- 如何将一个用户下的存储过程,包,函数单独备份出来
- OEM登陆问题,请指点~!
- 求教一个关于字符串的问题,杨哥快现身啊!!!!
- 数据导出的问题?
如果不加SUM()的话
SELECT CUST_NBR,REGION_ID,YEAR, SUM(TOT_SALES) AS CUST_TOT,
SUM(TOT_SALES) OVER(PARTITION BY REGION_ID,YEAR ORDER BY YEAR,REGION_ID) AS REGION_TOT
FROM ORDERS_TMP
GROUP BY REGION_ID,YEAR,CUST_NBR
ORDER BY YEAR,REGION_ID,CUST_NBR
上面语句报错,但是这里不是已经有一个sum了嘛...
但是分析函数是在结果集上再处理得到的,将其视为一个字段表达式(如果不是的话那么分析函数的查询都需要group by了),相当于是把一个含子循环的查询压缩到了一层。既然视为表达式,那么就要在group by后出现。但是放到group by 后面又会报错。。因为从本质上说分析函数那个是在结果集上再处理得到的,当然不能放到产生结果集的语句的group by中。所以需要再加个sum来躲过group by的形式检查。SQL>
SQL> SELECT t.sws_dm,t.sws_mc,SUM(ry_dm) ,SUM(ry_dm)over(PARTITION BY sws_dm)
2 FROM test t
3 GROUP BY t.sws_dm,t.sws_mc ;
SELECT t.sws_dm,t.sws_mc,SUM(ry_dm) ,SUM(ry_dm)over(PARTITION BY sws_dm)
FROM test t
GROUP BY t.sws_dm,t.sws_mc
ORA-00979: not a GROUP BY expression
SQL>
SQL> SELECT t.sws_dm,t.sws_mc,SUM(ry_dm) ,sum(SUM(ry_dm))over(PARTITION BY sws_dm)
2 FROM test t
3 GROUP BY t.sws_dm,t.sws_mc ;
SWS_DM SWS_MC SUM(RY_DM) SUM(SUM(RY_DM))OVER(PARTITIONB
---------- ---------- ---------- ------------------------------
1 第一税务所 510 510
2 第二税务所 1010 1010
3 第三税务所 1510 1510
4 第四税务所 1610 1610
5 第五税务所 500 500
SQL>
SQL> SELECT t.sws_dm,t.sws_mc,SUM(ry_dm)over(PARTITION BY sws_dm)
2 FROM test t
3 ;
SWS_DM SWS_MC SUM(RY_DM)OVER(PARTITIONBYSWS_
---------- ---------- ------------------------------
1 第一税务所 510
1 第一税务所 510
1 第一税务所 510
1 第一税务所 510
1 第一税务所 510
2 第二税务所 1010
2 第二税务所 1010
2 第二税务所 1010
2 第二税务所 1010
2 第二税务所 1010
3 第三税务所 1510
3 第三税务所 1510
3 第三税务所 1510
3 第三税务所 1510
3 第三税务所 1510
4 第四税务所 1610
4 第四税务所 1610
4 第四税务所 1610
4 第四税务所 1610
5 第五税务所 500
20 rows selected
SQL>
但是分析函数是在结果集上再处理得到的,将其视为一个字段表达式(如果不是的话那么分析函数的查询都需要group by了),相当于是把一个含子循环的查询压缩到了一层。既然视为表达式,那么就要在group by后出现。但是放到group by 后面又会报错。。因为从本质上说分析函数那个是在结果集上再处理得到的,当然不能放到产生结果集的语句的group by中。所以需要再加个sum来躲过group by的形式检查。
写错了,应该是子查询
那问一下上面这个sql的执行顺序问题,
先计算外层的sum还是里层的sum?
外层的sum按照region_id, year 分组吗?
里层的sum按照region_id,year,cust_nbr分组吗?
我对这句话有怀疑,我觉得内层sum是针对group by, 外层sum是针对 分析函数的。下面是我测试的代码
create table orders_tmp
(CUST_NBR NUMBER(5) NOT NULL,
REGION_ID NUMBER(5) NOT NULL,
SALESPERSON_ID NUMBER(5) NOT NULL,
YEAR NUMBER(4) NOT NULL,
MONTH NUMBER(2) NOT NULL,
TOT_ORDERS NUMBER(7) NOT NULL,
TOT_SALES NUMBER(11,2) NOT NULL);INSERT INTO orders_tmp VALUES('11','7',' 11 ','2001 ','7','2','12204 ') ;
INSERT INTO orders_tmp VALUES(' 4','5','4 ','2001 ',' 10','2','37802 ') ;
INSERT INTO orders_tmp VALUES(' 7','6','7 ','2001 ','2','3',' 3750 ' ) ;
INSERT INTO orders_tmp VALUES('10','6','8 ','2001 ','1','2','21691 ' ) ;
INSERT INTO orders_tmp VALUES('10','6','7 ','2001 ','2','3','42624 ' ) ;
INSERT INTO orders_tmp VALUES('15','7',' 12 ','2000 ','5','6',' 24 ' ) ;
INSERT INTO orders_tmp VALUES('12','7','9 ','2000 ','6','2','50658 ' ) ;
INSERT INTO orders_tmp VALUES(' 1','5','2 ','2000 ','3','2','44494 ' ) ;
INSERT INTO orders_tmp VALUES(' 1','5','1 ','2000 ','9','2','74864 ' ) ;
INSERT INTO orders_tmp VALUES(' 2','5','4 ','2000 ','3','2','35060 ' ) ;
INSERT INTO orders_tmp VALUES(' 2','5','4 ','2000 ','4','4',' 6454 ' ) ;
INSERT INTO orders_tmp VALUES(' 2','5','1 ','2000 ',' 10','4','35580' ) ;
INSERT INTO orders_tmp VALUES(' 4','5','4 ','2000 ',' 12','2','39190' ) ;SELECT CUST_NBR,REGION_ID,YEAR, SUM(TOT_SALES) AS CUST_TOT,
avg((sum(TOT_SALES)) OVER(PARTITION BY REGION_ID,YEAR ORDER BY YEAR,REGION_ID) AS REGION_TOT,
ROUND(RATIO_TO_REPORT(SUM(TOT_SALES)) OVER (PARTITION BY REGION_ID,YEAR),3) * 100 ||'%' AS CUST_SALES_RATIO
FROM ORDERS_TMP
GROUP BY REGION_ID,YEAR,CUST_NBR
ORDER BY YEAR,REGION_ID,CUST_NBR
SQL> SELECT t.sws_dm,t.sws_mc,SUM(ry_dm)over(PARTITION BY sws_dm)
2 FROM test t
3 ;
SWS_DM SWS_MC SUM(RY_DM)OVER(PARTITIONBYSWS_
---------- ---------- ------------------------------
1 第一税务所 510
1 第一税务所 510
1 第一税务所 510
1 第一税务所 510
1 第一税务所 510
2 第二税务所 1010
2 第二税务所 1010
2 第二税务所 1010
2 第二税务所 1010
2 第二税务所 1010
3 第三税务所 1510
3 第三税务所 1510
3 第三税务所 1510
3 第三税务所 1510
3 第三税务所 1510
4 第四税务所 1610
4 第四税务所 1610
4 第四税务所 1610
4 第四税务所 1610
5 第五税务所 500
20 rows selected
SQL>
不过有个语法错误 :avg((sum(TOT_SALES)) 改为avg((sum(TOT_SALES)))
这是将分析函数套在分组查询里,稍微改一下,应该也正确,但不那么容易造成误解SELECT CUST_NBR,max(REGION_ID),YEAR, SUM(TOT_SALES) AS CUST_TOT,
SUM(SUM(TOT_SALES)) OVER(PARTITION BY max(REGION_ID),YEAR ORDER BY YEAR,max(REGION_ID)) AS REGION_TOT
FROM ORDERS_TMP
GROUP BY YEAR,CUST_NBR
ORDER BY YEAR,CUST_NBR
SELECT CUST_NBR,REGION_ID,YEAR, SUM(TOT_SALES) AS CUST_TOT,
SUM(TOT_SALES) AS REGION_TOT
FROM ORDERS_TMP
GROUP BY REGION_ID,YEAR,CUST_NBR
ORDER BY YEAR,REGION_ID,CUST_NBR
;
然后对上面selelct出的结果,再按REGION_ID,YEAR分组同sum(REGION_TOT),然后得到结果。
两点:1.分析函数是在group by的基础上再次统计。分析函数分组时partition by后面的字段只能在CUST_NBR,REGION_ID,YEAR中选择。
2.外层的sum是分析函数使用的,内层的sum是group by使用的。这跟sql处理的顺序是一致的。