oracle分析函数问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle分析函数问题相关的知识,希望对你有一定的参考价值。

要求:部门从大到小排列,部门里各员工的薪水从高到低排列
表为 scott用户下emp表

SQL:1. select ename,sal,deptno, sum(sal) over (partition by deptno order by deptno desc,sal desc)
from emp;

2. select deptno,ename,sal, sum(sal) over (partition by deptno order by deptno desc,sal desc) dept_sum
sum(sal) over (order by deptno desc,sal desc) sum
from emp;

如果按照1的写法,deptno没有倒序排我都能想通,但是每个分区内的sal也没有倒序排。

写法2在1的基础上增加了一列sum(sal) over (order by deptno desc,sal desc) sum,使得整个表按照dept逆序,sal逆序进行排列了。

为什么会这样?

sum(sal) over (partition by deptno order by deptno desc,sal desc)意思是按照deptno分区对sal“对应deptno和sal连续”求和,而over函数中的order by是指在在同一deptno分区内进行排序 “连续求和”,同一分区内的deptno肯定相同,所以没有意义,而同一分区内的sal倒序“连续求和”,意味着本条记录的求和结果等于上条记录的求和结果+本条记录员工的sal,同一deptno中员工的sal是倒序的,而不是整个结果按照sal倒序,也不是对求和后的sal倒序排列。
** 注意连续求和的结果。
sum(sal) over (order by deptno desc,sal desc) 不按deptno分区,不按部门“连续”求总和追问

感谢你的回答让我一下子明白了,可惜百度只让采纳一个。

参考技术A

你的写法1 每个分区内的sal是倒序排列的

不过写法1中 order by deptno desc其实没有起到作用,因为有partition  by deptno子句,如果想要结果按deptno倒序排列,请把order by deptno desc移到最外层:

select ename, sal, deptno, 

       sum(sal) over(partition by deptno order by sal desc) 
  from emp order by  deptno desc;

写法2中,你去掉了partition子句,以整个表为分区,这时候计算需要按照 deptno & sal的指定排序进行,进而每一行顺序和写法1不同。

 

简单说,你想要最后结果按特定排序,请在外层使用order by子句

over后面的order by开窗子句影响计算顺序,并不决定最后结果的顺序。

追问

我那样写deptno没有倒序我能理解,但是我写的是over(partition by.....order by deptno desc sal desc)
你看我贴出来的第一张图,sal也不是倒序的啊?
我就弄不明白这个,难道说前面有了deptno desc 之后,那个sal desc就不执行了么?

追答

你的写法1里面,sal是按照每个分区倒序排序的

前面说过了 over后面的order by开窗子句影响计算顺序,并不决定最后结果的顺序
想要最后结果按特定排序,请在外层使用order by子句

本回答被提问者采纳
参考技术B select ename,sal,deptno,
sum(sal) over (partition by deptno order by deptno desc,sal desc)
from emp
order by order by deptno desc,sal desc;追问

这个是正解。
但是我想知道为什么不加最后的order by语句,前面括号里的order by后面加desc就毫无作用。
如果去掉最外层的order by 语句,结果既不会按照deptno倒序排列,也不会按sal倒序排列。
这个是不是说明只要over括号内有按照partition by 分区,over括号内后面的order by就不会执行倒序排列?

Oracle/SQLServer 中的分析函数高级教程 [关闭]

【中文标题】Oracle/SQLServer 中的分析函数高级教程 [关闭]【英文标题】:Advanced tutorial on analytic functions in Oracle/SQLServer [closed] 【发布时间】:2010-08-17 21:15:21 【问题描述】:

谁能推荐一个很好的教程(或者预定),在使用解析函数的覆盖高级的主题? STRONG> P>

我在找的东西,覆盖两个Oracle和SQLServer - 或两个独立的导游,如果一个不存在。一些使用功能平凡(LAG,LEAD,分组,百分位)的提议很好的例子将是有益的。

请不要点我在基本的Oracle的TechNet或MSDN参考材料 - 我已经看到了。我在寻找的东西,超越只是语法或简单的例子。 P>

【问题讨论】:

【参考方案1】:

我喜欢 PostgreSQL 实现的教程/介绍。它不仅涵盖了单纯的语法,还介绍了它们背后的概念。它很好地解释了窗口是什么以及窗口内的框架是什么。

PostgreSQL 语法与 Oracle 语法几乎兼容,所以这应该对您有所帮助。不确定其中有多少是在 SQL Server 中实现的。

无论如何,这是链接: http://www.pgcon.org/2009/schedule/events/128.en.html

直接链接到 PDF: http://www.pgcon.org/2009/schedule/attachments/98_Windowing%20Functions.pdf

【讨论】:

感谢您的链接。不幸的是,PostgreSQL 的分析实现看起来与 Oracle 和 SQLServer 不同——这限制了它对我的实用性。 没有。 PostgreSQL 的语法与 Oracle 的语法几乎相同。我认为 PDF 中的所有示例都可以直接在 Oracle 中运行而无需更改(使用“命名窗口”功能的示例除外)但是即使语法不够接近您的目的,请阅读 PDF。这是对窗口函数背后的“工作原理”的一个非常好的解释。【参考方案2】:

对于 Oracle,Tom Kyte 的专家 Oracle(签名版)中有一个很好的章节。 Expert Oracle 的早期版本缺少这一章。这比我见过的大多数在线文章都详细得多。

通过搜索“Tom Kyte Analytic Functions”在 Google 图书上进行预览

其中大部分内容应该适用于 SQL Server,尽管特定语法可能会有所不同(与往常一样)。

Apress 还有一本名为“Oracle SQL 食谱”的书——我不拥有这本书,但 Google 图书上的预览版(“分析函数食谱”)看起来可能非常有用——尽管它来自一个示例而不是基于概念的方法。

【讨论】:

以上是关于oracle分析函数问题的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 中的嵌套分析函数

oracle累加分析函数

[转]oracle 分析函数over

Oracle-分析函数之sum(...) over(...)

在分析函数中过滤行 - Oracle

Oracle分析函数入门