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 :用于计算 ...
随机推荐
- aix rksh 执行CLI命令行限制
su padmin -C "lsdev -dev hdisk9 -attr| grep unique_id"rksh: lsdev: 0403-006 Execute permis ...
- uva 10163 - Storage Keepers(01背包)
题目链接:10163 - Storage Keepers 题目大意:给出m为仓库的数量, 给出n为有守夜人的数量, 然后给出n个数值,为对应守夜人应付的酬劳,每个守夜人的能力与他需要的酬劳是相等的,并 ...
- JSP 文件上传下载系列之二[Commons fileUpload]
前言 关于JSP 文件上传的基础和原理在系列一中有介绍到. 这里介绍一个很流行的组件commons fileupload,用来加速文件上传的开发. 官方的介绍是: 让添加强壮,高性能的文件到你的se ...
- Neutron数据库同步错误 NotImplementedError: No support for ALTER of constraints in SQLite dialect
错误信息 root@controller:~# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron. ...
- ftk学习记(icon篇)
[声明:版权全部,欢迎转载.请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 在開始今天的文章之前.我们还是先看一下上一节的效果图. 大家能够參照上一节的解说,是不是存在这种 ...
- CSS 根据数据显示样式
在低版本IE时代,我们想让数据根据其值显示不同的样式可能需要直接从服务器端输出时为不同的数据添加相应的class.但现在,通过属性选择器+伪元素+属性选择符,这三个东西混合使用就可以让数据根据其值以不 ...
- C# 类型的创建
类 类是最普通的引用类型,最简单的声明如下所示: class YourNameClass { } 更复杂的类可以拥有以下这些选项: 置于关键字class前面的:属性(attributes)与class ...
- 使用ionic与cordova(phonegap)进行轻量级app开发前的环境配置与打包安卓apk过程记录
前言 有人说:"如果你恨一个人,就让ta去接触cordova(phonegap)",这是因为这里面的水很深,坑很多,真让人不是一般地发狂.或许有幸运的人儿基本顺顺利利就配置完环境 ...
- C趣味100道之58.拉丁方的一些想法。
题目如上. 思路(未写) 完整代码如下: #include<iostream> #include<queue> #include<math.h> using nam ...
- Linux_常用命令
文件搜索 -find -locate -grep 字符串搜索 -grep 过滤 -grep/find/xargs/ 编辑 -sed 待续....