您的位置:首页 > 数据库 > Oracle

oracle分析函数——over

2015-10-10 10:57 555 查看
原文见我得博客:点击打开链接

1、分析函数:

1)分析函数:
Oracle从8.1.6开始提供分析函数,专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值。分析函数用于计算基于组的某种聚合值。

它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行。普通的聚合函数用group by分组,每个分组返回一个统计值;而分析函数采用partitionby分组,并且每组每行都可以返回一个统计值。

2)开窗函数:
开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化。例如over函数

3)分析函数的形式
分析函数带有一个开窗函数over(),在窗口函数中包含三个分析子句:分组(partitionby), 排序(order by), 窗口(rows) ,他们的使用形式如下:over(partition
by xxx order by yyy rows between zzz)。
注:窗口子句在这里我只说rows方式的窗口,range方式和滑动窗口也不提。

例如:统计函数+over()、排序函数+over()、数据分布函数+over()、统计分析函数+over()。

2、开窗函数:

1)over(order by col)
:可以理解为按照col列排序进行累计,orderby是个默认的开窗函数
SQL> select *from t_over;


A
----------

1

2

2

2

3

4

5

6

7

9

10 rows selected.

SQL> selecta,avg(a)over(order by a),sum(a)over(order by a) from t_over;


A ***G(A)OVER(ORDERBYA) SUM(A)OVER(ORDERBYA)
------------------------------ --------------------

1 1 1

2 1.75 7

2 1.75 7

2 1.75 7

3 2 10

4 2.33333333 14

5 2.71428571 19

6 3.125 25

7 3.55555556 32

9 4.1 41

10 rows selected.

2)分区(partition by col):按照col进行分区统计
SQL> selecta,sum(a)over(partition by a) from t_over;


A SUM(A)OVER(PARTITIONBYA)
----------------------------------

1 1

2 6

2 6

2 6

3 3

4 4

5 5

6 6

7 7

9 9

10 rows selected.

3)范围over(order by salary range between 5preceding and 5 following):窗口范围为当前行数据幅度减5加5后的范围内的。
SQL> selecta,sum(a)over(order by a range between 2 preceding and 2 following) from t_over;


ASUM(A)OVER(ORDERBYARANGEBETWEEN2PRECEDINGAND2FOLLOWING)
-----------------------------------------------------------------
1 10 -- 1减2加2范围是-1到3,a在这个范围内有1、2、2、2、3,所以是10

2 14

2 14

2 14

3 19

4 24
5 25 -- 5减2加2范围是3到7,a在这个范围内有3、4、5、6、7,所以是25

6 22

7 27
9 16 -- 9减2加2范围是7到11,a在这个范围内有7、9,所以是16

10 rows selected.

4)范围over(order by salary rows between 5preceding and 5 following):窗口范围为当前行前后各移动5行。
SQL> selecta,sum(a)over(order by a rows between 2 preceding and 2 following) from t_over;


ASUM(A)OVER(ORDERBYAROWSBETWEEN2PRECEDINGAND2FOLLOWING)
----------------------------------------------------------------

1 5

2 7

2 10

2 13

3 16

4 20

5 25

6 31

7 27

9 22

10 rows selected.

5)可以混合使用:
SELECT E.DEPTNO,
E.EMPNO,
E.ENAME,
E.SAL,

LAST_VALUE(E.SAL)
OVER(PARTITION BY E.DEPTNO

ORDER BY E.SAL

ROWS
--unbounded preceding and unbounedfollowing针对当前所有记录的前一条、后一条记录,也就是表中的所有记录
--unbounded:不受控制的,无限的
--preceding:在...之前
--following:在...之后
BETWEEN UNBOUNDED PRECEDING ANDUNBOUNDED FOLLOWING) MAX_SAL
FROM EMP E;

3、常见分析函数:

• row_number() over(partition by ... order by ...)

• rank() over(partition by ... order by ...)

• dense_rank() over(partition by ... order by ...)

• count() over(partition by ... order by ...)

• max() over(partition by ... order by ...)

• min() over(partition by ... order by ...)

• sum() over(partition by ... order by ...)

• avg() over(partition by ... order by ...)

• first_value() over(partition by ... order by ...)

• last_value() over(partition by ... order by ...)

• lag() over(partition by ... order by ...)

• lead() over(partition by ... order by ...)

1)Row_number函数返回一个唯一的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增。例如:row_number()over(partition by col1 orderby col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。



与rownum的区别在于:使用rownum进行排序的时候是先对结果集加入伪列rownum然后再进行排序,而此函数在包含排序从句后是先排序再计算行号码。row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开始排序)。



2)Dense_rank函数返回一个唯一的值,除非当碰到相同数据时,此时所有相同数据的排名都是一样的。



3)Rank函数返回一个唯一的值,除非遇到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名。



SQL> select region_id, customer_id, sum(customer_sales) total,

2 rank() over(order by sum(customer_sales) desc) rank,

3 dense_rank() over(order by sum(customer_sales) desc) dense_rank,

4 row_number() over(order by sum(customer_sales) desc) row_number

5 from user_order

6 group by region_id, customer_id;



REGION_ID CUSTOMER_ID TOTAL RANK DENSE_RANK ROW_NUMBER

---------- ----------- ---------- ---------- ---------- ----------


8 18 1253840 11 11 11

5 2 1224992 12 12 12

9 23 1224992 12 12 13

9 24 1224992 12 12 14

10 30 1216858 15 13 15



30 rows selected.

first_value()
last_value()

FIRST_VALUE 返回组中数据窗口的第一个值

LAST_VALUE 返回组中数据窗口的最后一个值。

lag()lead():
Lag和Lead函数可以在一次查询中取出同一字段的前N行的数据和后N行的值。
语法:lag(exp_str,offset,defval) over()

exp_str 是要做对比的字段;

offset 是exp_str字段的偏移量 比如说 offset 为2 则 拿exp_str的第一行和第三行对比,第二行和第四行,依次类推,offset的默认值为1!

defval是当该函数无值可用的情况下返回的值。Lead函数的用法类似。

原文见我得博客:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: