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

query_partition_clause::=


Description of the illustration query_partition_clause.gif

order_by_clause::=


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子句的更多相关文章

  1. oracle 分析函数和开窗函数

    最近遇到一个需求,将查询出的数据按照地区分组,随机取出每个区域的2条数据,这里用到了oracle的分析和开窗函数: 最终写出的sql如下: select * from (select region,r ...

  2. oracle分析函数技术详解(配上开窗函数over())

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  3. oracle中where 子句和having子句中的区别

    1.where 不能放在GROUP BY 后面 2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用相当于WHERE 3.WHERE 后面的条件中不能有聚集函数 ...

  4. 在oracle中where 子句和having子句中的区别

    在oracle中where 子句和having子句中的区别 1.where 不能放在GROUP BY 后面 2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用 ...

  5. Oracle学习之start with...connect by子句的用法

    转自:http://www.blogjava.net/xzclog/archive/2010/03/05/314642.html,多谢博主分享 Oracle中start with…connect by ...

  6. SQL Server开窗函数之OVER子句、PARTITION BY 子句

    开窗函数与聚合函数一样,都是对行的集合组进行聚合计算.它用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同 ...

  7. oracle中where子句和having子句中的区别

    1.where  不能放在GROUP BY 后面2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用相当于WHERE3.WHERE  后面的条件中不能有聚集函数 ...

  8. [转]oracle 分析函数over

      oracle 分析函数over 分析函数(OVER) 目录: =============================================== 1.Oracle分析函数简介 2. O ...

  9. Oracle分析函数——函数列表

    --------------聚合函数 SUM :该函数计算组中表达式的累积和 MIN :在一个组中的数据窗口中查找表达式的最小值 MAX :在一个组中的数据窗口中查找表达式的最大值 AVG :用于计算 ...

随机推荐

  1. Csharp实现快速排序

    public void QuickSort(int[] arr, int left, int right) //快速排序 { //先从数列中去处一个数作为基准数 //分区过程,将比这个数大的数全放在他 ...

  2. ES6笔记③

    1.查找关键字  includes(); 返回布尔值 //①:includes -->代替-->indexof-->返回布尔值 var str = "769909303&q ...

  3. 控制台下的计算器——C++实现

    最近这段时间看操作系统的东西看的头晕脑胀的,所以先停个一晚上,写个控制台下的计算器,来练练栈的使用. 首先,分析一下要完成的东西.输入肯定使用string类来输入的,然后第一步,就是把string的字 ...

  4. CentOS 配置防火墙操作实例(启、停、开、闭端口)CentOS Linux-FTP/对外开放端口(接口)TomCat相关

    链接地址:http://blog.csdn.net/jemlee2002/article/details/7042991 CentOS 配置防火墙操作实例(启.停.开.闭端口): 注:防火墙的基本操作 ...

  5. QF——网络之JSON解析和XML解析

    JSON解析和XML解析: 用苹果原生的代理方式的网络请求后返回的都是二进制数据(NSData). 若是json,则通过NSJSONSerialization把NSData数据转换为JSON对象. N ...

  6. mysql获取各种日期

    select curdate(); --获取当前日期 select last_day(curdate()); --获取当月最后一天. select DATE_ADD(curdate(),interva ...

  7. ExtJS4.2 Ext.grid.panel Store更改后刷新表格

    //////////////////////// // Prepare store //////////////////////// // prepare fields and columns var ...

  8. Android 获取有规律资源Id解决方案

    在多个有规律的资源ID获取的时候,可以使用getIdentifier方法来获取,来获取. 用到场景:工具类打成.jar包的时候,有时候会需要引用到res中的资源,这时候不能将资源一起打包,只能通过反射 ...

  9. javaEE简答题整理

    1. 什么是JavaEE?其编程思想是什么? JavaEE是一个标准的中间件体系结构,是企业分布式应用开发标准.JavaEE的编程思想是组件—容器. 2. 为什么提出JavaEE体系结构? (1)为满 ...

  10. codeforces 645C . Enduring Exodus 三分

    题目链接 我们将所有为0的位置的下标存起来. 然后我们枚举左端点i, 那么i+k就是右端点. 然后我们三分John的位置, 找到下标为i时的最小值. 复杂度 $ O(nlogn) $ #include ...