Oracle分析函数之开窗子句-即WINDOWING子句
Oracle的分析函数,对我们进行统计有很大的帮助,可以避免一些子查询等操作,在统计中,我们对开窗函数的接触较少,下面主要介绍下开窗函数的使用;
http://www.itpub.net/thread-1241311-1-1.html
http://www.oracle-base.com/articles/misc/analytic-functions.php#windowing_clause
http://blog.sina.com.cn/s/blog_70cea94b0100xi46.html
首先我们介绍下分析函数的语义
(分为range和row):缺省时相当于RANGE UNBOUNDED PRECEDING
值域窗(RANGE WINDOW) 如:RANGE N PRECEDING, 仅对数值或日期类型有效,选定窗为排序后当前行之前,某列(即排序列)值大于/小于(当 前 行该列值 –/+ N)的所有行,因此与ORDER BY子句有关系。
行窗(ROW WINDOW)如:ROWS N PRECEDING ,选定窗为当前行及之前N行。还可以加上BETWEEN AND 形式,例如RANGE BETWEEN m PRECEDING AND n FOLLOWING,表示每行对应的数据窗口是之前m行与之后n行内。
SELECT empno,
sal,
mgr,
deptno,
SUM(sal) over(PARTITION BY deptno ORDER BY sal RANGE BETWEEN 0 PRECEDING AND 100 FOLLOWING) dd
FROM emp;
其中:上面代表按DEPARTMENT_ID分区,按SALARY升序排序,汇总当前SALARY到比当前SALARY大100之间的SALARY总和。、
按DEPARTMENT_ID分区,按SALARY升序排序,汇总当前SALARY到比当前SALARY大100之间的SALARY总和。
Analytic functions are commonly used to compute cumulative, moving, centered, and reporting aggregates.
analytic_function::=
Description of the illustration analytic_function.gif
analytic_clause::=
Description of the illustration analytic_clause.gif
Description of the illustration query_partition_clause.gif
Description of the illustration order_by_clause.gif
windowing_clause ::=
Description of the illustration windowing_clause.gif
上面的这张图片是开窗函数的具体语法,我们可以参照这个语法。
值的开窗,该值只能是日期和数字
我有这样一个要求:
1、查询的结果按照值排序,如sql:select value from t;
结果示例如下:
50
70
90
130
160
190
2、对数据进行分组。从上述数组第一个值开始,+50之内的值作为同一组值,如果超出50了,则开始一个新的分组。示例如下
50 50
70 50
90 50
130 130
160 130
190 190
3、最终结果是统计每组的个数。结果示例:
50 3
130 2
190 1
原帖见:http://www.itpub.net/thread-985707-1-1.html
WITH T AS (
SELECT 50 N FROM DUAL UNION ALL
SELECT 70 N FROM DUAL UNION ALL
SELECT 90 N FROM DUAL UNION ALL
SELECT 130 N FROM DUAL UNION ALL
SELECT 160 N FROM DUAL UNION ALL
SELECT 190 N FROM DUAL
)
SELECT *
FROM (SELECT n,
row_number() OVER(ORDER BY n) rn,
COUNT(*) OVER(ORDER BY n RANGE BETWEEN CURRENT ROW AND 50 FOLLOWING) cn
FROM t)
START WITH rn = 1
CONNECT BY RN = PRIOR CN + PRIOR RN;
在这里,我们通过数值开窗函数,统计了每个范围内的值,然后,通过构造条件,去进行connect by,
在这里,通过让cn和rn去相加,作为connect by的条件,这个思路非常的好,很值得我们思考
在统计的过程,我们往往只是需要去构造一个场景,条件。
我有这样一个要求:
1、查询的结果按照值排序,如sql:select value from t;
结果示例如下:
50
70
90
130
160
190
2、对数据进行分组。从上述数组第一个值开始,+50之内的值作为同一组值,如果超出50了,则开始一个新的分组。示例如下
50 50
70 50
90 50
130 130
160 130
190 190
3、最终结果是统计每组的个数。结果示例:
50 3
130 2
190 1
这样一个要求,怎么用一个sql语句实现呢。
谢谢大家!
原帖见:http://www.itpub.net/thread-985707-1-1.html
通过如下的SQL可以实现上面的要求:
WITH T AS (
SELECT 1 N FROM DUAL UNION ALL
SELECT 3 N FROM DUAL UNION ALL
SELECT 4 N FROM DUAL UNION ALL
SELECT 7 N FROM DUAL UNION ALL
SELECT 10 N FROM DUAL UNION ALL
SELECT 11 N FROM DUAL UNION ALL
SELECT 12 N FROM DUAL UNION ALL
SELECT 12 N FROM DUAL UNION ALL
SELECT 19 N FROM DUAL UNION ALL
SELECT 20 N FROM DUAL
)
SELECT T2.N
,DENSE_RANK() OVER(ORDER BY T2.G) G
FROM (
SELECT T.N
,MAX(T1.N)OVER(ORDER BY T.N) G
FROM (
SELECT N
FROM (
SELECT N
,COUNT(*) OVER(ORDER BY N RANGE BETWEEN CURRENT ROW AND 4 FOLLOWING) CNT
,ROW_NUMBER()OVER(ORDER BY N) RN
FROM T
)
CONNECT BY RN = PRIOR RN + PRIOR CNT
START WITH RN = 1
) T1 , T
WHERE T1.N(+) = T.N
) T2;
在这里,我们需要关注connect by,dense rank函数和 ,MAX(T1.N)OVER(ORDER BY T.N) G这个用法。
下面是高手用with递归解决的例子,当前也可以用我们熟悉的connect by解决该问题
WITH T AS
(SELECT 1 N
FROM DUAL
UNION ALL
SELECT 4 N
FROM DUAL
UNION ALL
SELECT 3 N
FROM DUAL
UNION ALL
SELECT 7 N
FROM DUAL
UNION ALL
SELECT 10 N
FROM DUAL
UNION ALL
SELECT 11 N
FROM DUAL
UNION ALL
SELECT 12 N
FROM DUAL
UNION ALL
SELECT 12 N
FROM DUAL
UNION ALL
SELECT 19 N
FROM DUAL
UNION ALL
SELECT 20 N FROM DUAL),
v AS
(SELECT n, row_number() over(ORDER BY n) rn FROM t),
v1(flag,
n,
rn) AS
(SELECT n, n, rn
FROM v
WHERE rn = 1
UNION ALL
SELECT CASE
WHEN v.n - v1.flag >= 5 THEN
v.n
ELSE
v1.flag
END,
v.n,
v.rn
FROM v, v1
WHERE v.rn = v1.rn + 1)
SELECT * FROM v1
当然也有高手用MODEL语句实现了该功能,请查看原帖。
Oracle分析函数之开窗子句-即WINDOWING子句的更多相关文章
- oracle 分析函数和开窗函数
最近遇到一个需求,将查询出的数据按照地区分组,随机取出每个区域的2条数据,这里用到了oracle的分析和开窗函数: 最终写出的sql如下: select * from (select region,r ...
- oracle分析函数技术详解(配上开窗函数over())
一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...
- oracle中where 子句和having子句中的区别
1.where 不能放在GROUP BY 后面 2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用相当于WHERE 3.WHERE 后面的条件中不能有聚集函数 ...
- 在oracle中where 子句和having子句中的区别
在oracle中where 子句和having子句中的区别 1.where 不能放在GROUP BY 后面 2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用 ...
- Oracle学习之start with...connect by子句的用法
转自:http://www.blogjava.net/xzclog/archive/2010/03/05/314642.html,多谢博主分享 Oracle中start with…connect by ...
- SQL Server开窗函数之OVER子句、PARTITION BY 子句
开窗函数与聚合函数一样,都是对行的集合组进行聚合计算.它用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同 ...
- oracle中where子句和having子句中的区别
1.where 不能放在GROUP BY 后面2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用相当于WHERE3.WHERE 后面的条件中不能有聚集函数 ...
- [转]oracle 分析函数over
oracle 分析函数over 分析函数(OVER) 目录: =============================================== 1.Oracle分析函数简介 2. O ...
- Oracle分析函数——函数列表
--------------聚合函数 SUM :该函数计算组中表达式的累积和 MIN :在一个组中的数据窗口中查找表达式的最小值 MAX :在一个组中的数据窗口中查找表达式的最大值 AVG :用于计算 ...
随机推荐
- Guava缓存器源码分析——删除消息
Guava缓存器的删除消息机制 测试代码—— LoadingCache<String, Integer> cache = CacheBuilder.newBuild ...
- warning C4133: “函数”: 从“char [5]”到“LPCWSTR”的类型不兼容
弹窗打开一个网页,但是报错,代码如下: #include <stdio.h> #include <windows.h> void main() { ShellExecute(, ...
- 2014ACM/ICPC亚洲区广州站 Song Jiang's rank list
欢迎参加——每周六晚的BestCoder(有米!) Song Jiang's rank list Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- UNIX网络编程---传输层:TCP、UDP、SCTP(二)
UNIX网络编程----传输层:TCP.UDP.SCTP 一.概述 本章的焦点是传输层:包括TCP.UDP.和SCTP(流控制传输协议).SCTP是一个较新的协议,最初设计用于跨因特网传输电话信令. ...
- 浅谈android的selector,背景选择器
shape和selector的结合使用 (2013-04-07 11:11:00) 转载▼ 分类: android 1.Shape (1)作用:XML中定义的几何形状 (2)位置:res/draw ...
- Secret of Success(成功的秘诀)
A youngman asked Socrates the secret of Success. Socrates told the youngman to meet him near the riv ...
- Android开发之自定义Spinner样式的效果实现(源代码实现)
android系统自带的Spinner样式是远远满足不了我们实际开发过程中对Spinner UI风格的要求,因此我们肯定需要为了切合整个应用的风格,修改我们的Spinner样式.系统给我们提供了两种常 ...
- android 混淆配置
proguard 原理Java代码编译成二进制class 文件,这个class 文件也可以反编译成源代码 ,除了注释外,原来的code 基本都可以看到.为了防止重要code 被泄露,我们往往需要混淆( ...
- asp.net多图片上传同时保存对每张图片的描述
前台aspx //图片预览和描述 function previewImage(file) { var div = document.getElementById('preview'); div.inn ...
- 为SharePoint 2010中的FBA创建自定义登录页面
SharePoint 2010中默认的FBA登录页面非常简单,只提供了一个Asp.Net的Login控件,让用户输入用户名和密码.在大多数情况下,我们需要定制这个页面以满足一些安全需求,比如为登录页面 ...