oracle 分析函数问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 分析函数问题相关的知识,希望对你有一定的参考价值。
就以scott用户下的emp表为例,执行下列2条语句得到的结果是不同的,不知道该作何理解。
括号中order by后面的先后顺序跟什么有关呢?
select ename,sal,sum(sal) over (order by ename,deptno) from emp_test order by deptno;
select ename,sal,sum(sal) over (order by deptno,ename) from emp_test order by deptno;
首先第2个语句就不解释了。是正常的。而且你也写的怪。(order by deptno,ename)这个顺序是先按照ename排再按照deptno排。后面你又写个order by deptno完全没有意义。
解释第一个:
第一个是这样的。你先按照deptno排。然后按照ename排后的结果是这样的。也就是假设你别加最后个order by deptno的时候。
然后你又按照最后的order by deptno来排序。那肯定又是按部门编号从小到大的默认来排序咯。
所以肯定就是部门编号从10开始算。结果就是如上面那样啦。
追问你的意思是说...over括号里面的order by是从右边的开始先排序?和普通的order by排序顺序不同?
比如 ....over(order by a,b,c)...
这样写的话是先按照C排序,再排B,A.... 这样?
普通的也是一样。按照从右向左排开始排序。
后悔帮你回答了问题。你采纳的就是拿结果给你看看。根本就没帮你分析也采纳。
看懂了你也没真的明白。
over(order by a,b,c)...
这样写的话是先按照C排序,再排B,A..对的。,
首先我很感谢你啊,如果你及时回答追问的话,这个分是你的。
然后我想说采纳他是因为他是最终解决我疑惑的人,我疑惑就是那个顺序到底是从左到右还是从右到左,他给出了拆分步骤,所以我明白了。
最后我想说 实验了下不管是over (order by a,b,c)还是普通的order by 都是从a到b到c这样排序,而不是从右到左的。
还是感谢你的耐心回答。
select ename,sal,sum(sal) over (order by ename,deptno) from emp_test ;
你就说这条语句是不是和我的第一个图的结果是一样吗。
按照我现在的理解,你上面那条语句就是按照ename的累加
也就和你的第一张图是一个效果。
但是你在后面说是先按照deptno排列,再按照ename排列(也就是你说的从右到左),这点让我产生疑问over (order by a,b) 是先a还是先b,进而发出追问。
追问之后你没及时回答,而被采纳的那位回答我是先a后b,并给出拆分过程。
经过我自己的实验后,也确认应该是先按a排再按b排,所以采纳了他的。
哦
参考技术Aover(order by col1, col2...)
是先按照col1, col2排序后,然后计算sal值——从第一行记录直到当前行记录计算sum(sal)
比如你的第一句,其实是对如下的表的每一行,计算从第一行到当前行的sum(sal)
SQL> select ename, deptno, sal from emp order by ename, deptno;ENAME DEPTNO SAL
---------- ------ ---------
ADAMS 20 1100.00
ALLEN 30 1600.00
BLAKE 30 2850.00
CLARK 10 2450.00
FORD 20 3000.00
JAMES 30 950.00
JONES 20 2975.00
KING 10 5000.00
MARTIN 30 1250.00
MILLER 10 1300.00
SCOTT 20 3000.00
SMITH 20 800.00
TURNER 30 1500.00
WARD 30 1250.00
计算的结果形如:
SQL> select ename, deptno, sal , sum(sal) over (order by ename, deptno) from emp ;ENAME DEPTNO SAL SUM(SAL)OVER(ORDERBYENAME,DEPT
---------- ------ --------- ------------------------------
ADAMS 20 1100.00 1100
ALLEN 30 1600.00 2700
BLAKE 30 2850.00 5550
CLARK 10 2450.00 8000
FORD 20 3000.00 11000
JAMES 30 950.00 11950
JONES 20 2975.00 14925
KING 10 5000.00 19925
MARTIN 30 1250.00 21175
MILLER 10 1300.00 22475
SCOTT 20 3000.00 25475
SMITH 20 800.00 26275
TURNER 30 1500.00 27775
WARD 30 1250.00 29025
计算完毕后,才会使用外层的order by deptno排序;
同理,第二句是针对以下数据集来计算
SQL> select ename, deptno, sal from emp order by deptno, ename;ENAME DEPTNO SAL
---------- ------ ---------
CLARK 10 2450.00
KING 10 5000.00
MILLER 10 1300.00
ADAMS 20 1100.00
FORD 20 3000.00
JONES 20 2975.00
SCOTT 20 3000.00
SMITH 20 800.00
ALLEN 30 1600.00
BLAKE 30 2850.00
JAMES 30 950.00
MARTIN 30 1250.00
TURNER 30 1500.00
WARD 30 1250.00
计算结果如下
SQL> select ename, deptno, sal , sum(sal) over (order by deptno, ename) from emp ;ENAME DEPTNO SAL SUM(SAL)OVER(ORDERBYDEPTNO,ENA
---------- ------ --------- ------------------------------
CLARK 10 2450.00 2450
KING 10 5000.00 7450
MILLER 10 1300.00 8750
ADAMS 20 1100.00 9850
FORD 20 3000.00 12850
JONES 20 2975.00 15825
SCOTT 20 3000.00 18825
SMITH 20 800.00 19625
ALLEN 30 1600.00 21225
BLAKE 30 2850.00 24075
JAMES 30 950.00 25025
MARTIN 30 1250.00 26275
TURNER 30 1500.00 27775
WARD 30 1250.00 29025
然后再对deptno排序得出最终结果。
简单说,over后面的 order by 影响了你计算的顺序,因此得出的结果是不同的。
本回答被提问者采纳 参考技术B 其实很简单:先按照第一个(ename)升序排序,再按第二个deptno升序排列使用分析函数 Oracle 分组
【中文标题】使用分析函数 Oracle 分组【英文标题】:Group by using Analytical function Oracle 【发布时间】:2014-09-04 19:39:28 【问题描述】:我有以下演示代码。 我怎样才能得到想要的输出。它只是没有出现在我的脑海中:-(。它必须是一个简单的改变。
WITH Abc AS (SELECT 'AB' AS code,'Z12' AS des, 123 AS tk FROM dual UNION
SELECT 'AB','Z14',234 FROM dual UNION
SELECT 'ACB','D12',34 FROM dual UNION
SELECT 'ACB','D12',36 FROM dual UNION
SELECT 'ACB','F12',35 FROM dual UNION
SELECT 'ABX','G44',243 FROM dual UNION
SELECT 'ABX','H44',654 FROM dual UNION
SELECT 'ABX','J12',534 FROM dual UNION
SELECT 'ABQ',NULL,356 FROM dual)
SELECT DISTINCT tk,code,des ,code||'_'||row_number () OVER (PARTITION BY code ORDER BY code,des ) AS str FROM abc
ORDER BY 2,3;
输出:
tk code des str
--- --- --- ---
123 AB Z12 AB_1
234 AB Z14 AB_2
356 ABQ ABQ_1
243 ABX G44 ABX_1
654 ABX H44 ABX_2
534 ABX J12 ABX_3
34 ACB D12 ACB_1 --- ACB_1
36 ACB D12 ACB_2 ----I want ACB_1 here too since desc is same for that code
35 ACB F12 ACB_3
【问题讨论】:
【参考方案1】:**USE RANK() instead of rownumber()**
WITH Abc AS (SELECT 'AB' AS code,'Z12' AS des, 123 AS tk FROM dual UNION
SELECT 'AB','Z14',234 FROM dual UNION
SELECT 'ACB','D12',34 FROM dual UNION
SELECT 'ACB','D12',36 FROM dual UNION
SELECT 'ACB','F12',35 FROM dual UNION
SELECT 'ABX','G44',243 FROM dual UNION
SELECT 'ABX','H44',654 FROM dual UNION
SELECT 'ABX','J12',534 FROM dual UNION
SELECT 'ABQ',NULL,356 FROM DUAL)
SELECT DISTINCT TK,CODE,DES ,CODE||'_'||rank() OVER (PARTITION BY CODE ORDER BY CODE,DES ) AS STR FROM ABC
ORDER BY 2,3;
【讨论】:
非常感谢..确实有效,令人惊讶的是我在使用排名之前尝试过,但没有成功,也许我做错了什么。以上是关于oracle 分析函数问题的主要内容,如果未能解决你的问题,请参考以下文章