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. Android 给Button加个监听

    1.日期设置控件:DatePickerDialog 2.时间设置控件:TimePickerDialog 实例代码 1.页面添加两个Button,单击分别显示日期设置控件和时间设置控件,还是有TextV ...

  2. 浅谈css盒模型

    在我们网页上的每一个元素,一个按钮,一段文本,一张图片等等,浏览器都将它们当做一个“盒子”看待,并把这样的盒子称为盒模型(box model).使用Chrome的右键>审查元素对某个网页上的元素 ...

  3. Effective C++ 条款18

    让接口easy被正确使用,不easy被误用 如题目,我们自己的程序接口是面向用户的,程序的目的不可是解决这个问题,并且要让用户easy使用.所以.必须保证我们的程序接口具有非常强的鲁棒性. 怎么保证接 ...

  4. UITabBarController 笔记(三) UITabBarController 配合 UINavigationController 的使用

    建个空的iOS工程 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictiona ...

  5. A Guide to the Multiboot Process

    A Guide to the Multiboot Process The XP and Vista boot process in general.The Windows dual and multi ...

  6. jQuery load()和ready()

    ready与load谁先执行: 大家在面试的过程中,经常会被问到一个问题:ready与load那一个先执行,那一个后执行?答案是ready先执行,load后执行. DOM文档加载的步骤: 要想理解为什 ...

  7. org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session

    出错原因很简单:数据库服务没开,自然就打不开Session了.

  8. mysql utf8_bin跟utf8_general_ci的区别

    ci是 case insensitive, 即 "大小写不敏感", a 和 A 会在字符判断中会被当做一样的; bin 是二进制, a 和 A 会别区别对待. 例如你运行: SEL ...

  9. 在eclipse上安装 Marketplace Client

    Eclipse Marketplace是个插件应用商店,很实用的一个功能. 打开 eclipse,help--Eclipse Marketplace Client就能找到 有的eclipse中没有这个 ...

  10. python----设置默认编码

    问题:python的默认编码是ascii.在处理中文的时候可能会出现乱码的情况:这个时候我们就需要把编码设置为对应的编码了. 解决方案: 对python文件的头部做如下修改 import sys re ...