搜档网
当前位置:搜档网 › Oracle分析函数使用介绍

Oracle分析函数使用介绍

Oracle分析函数使用介绍
Oracle分析函数使用介绍

Oracle 分析函数使用介绍

分析函数是oracle816引入的一个全新的概念,为我们分析数据提供了一种简单高效的处理方式.在分析函数出现以前,我们必须使用自联查询,子查询或者内联视图,甚至复杂的存储过程实现的语句,现在只要一条简单的sql语句就可以实现了,而且在执行效率方面也有相当大的提高.下面我将针对分析函数做一些具体的说明.

下面给大家介绍一下以下几个函数的使用方法

1. 自动汇总函数rollup,cube,

2. rank 函数, rank,dense_rank,row_number

3. lag,lead函数

4. sum,avg,的移动增加,移动平均数

5. ratio_to_report报表处理函数

6. first,last取基数的分析函数

基础数据

06:34:23 SQL> select * from t;

BILL_MONTH AREA_CODE NET_TYPE LOCAL_FARE

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

200405 5761 g 7393344.04

200405 5761 j 5667089.85

200405 5762 g 6315075.96

200405 5762 j 6328716.15

200405 5763 g 8861742.59

200405 5763 j 7788036.32

200405 5764 g 6028670.45

200405 5764 j 6459121.49

200405 5765 g 13156065.77

200405 5765 j 11901671.70

200406 5761 g 7614587.96

200406 5761 j 5704343.05

200406 5762 g 6556992.60

200406 5762 j 6238068.05

200406 5763 g 9130055.46

200406 5763 j 7990460.25

200406 5764 g 6387706.01

200406 5764 j 6907481.66

200406 5765 g 13562968.81

200406 5765 j 12495492.50 200407 5761 g 7987050.65 200407 5761 j 5723215.28 200407 5762 g 6833096.68 200407 5762 j 6391201.44 200407 5763 g 9410815.91 200407 5763 j 8076677.41 200407 5764 g 6456433.23 200407 5764 j 6987660.53 200407 5765 g 14000101.20 200407 5765 j 12301780.20 200408 5761 g 8085170.84 200408 5761 j 6050611.37 200408 5762 g 6854584.22 200408 5762 j 6521884.50 200408 5763 g 9468707.65 200408 5763 j 8460049.43 200408 5764 g 6587559.23 200408 5764 j 7342135.86 200408 5765 g 14450586.63 200408 5765 j 12680052.38

40 rows selected.

Elapsed: 00:00:00.00

使用rollup函数的介绍

下面是直接使用普通sql语句求出各地区的汇总数据的例子

06:41:36 SQL> set autot on

06:43:36 SQL> select area_code,sum(local_fare) local_fare

06:43:50 2 from t

06:43:51 3 group by area_code

06:43:57 4 union all

06:44:00 5 select '合计' area_code,sum(local_fare) local_fare 06:44:06 6 from t

06:44:08 7 /

AREA_CODE LOCAL_FARE

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

5761 54225413.04

5762 52039619.60

5763 69186545.02

5765 104548719.19

合计 333157065.31

6 rows selected.

Elapsed: 00:00:00.03

Execution Plan

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

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=1310 Bytes=24884)

1 0 UNION-ALL

2 1 SORT (GROUP BY) (Cost=5 Card=1309 Bytes=24871)

3 2 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=1309 Bytes=24871)

4 1 SORT (AGGREGATE)

5 4 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=1309 Bytes=17017)

Statistics

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

0 recursive calls

0 db block gets

6 consistent gets

0 physical reads

0 redo size

561 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

6 rows processed

下面是使用分析函数rollup得出的汇总数据的例子

06:44:09 SQL> select nvl(area_code,'合计') area_code,sum(local_fare) local_fare

06:45:26 2 from t

06:45:30 3 group by rollup(nvl(area_code,'合计'))

06:45:50 4 /

AREA_CODE LOCAL_FARE

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

5761 54225413.04

5762 52039619.60

5763 69186545.02

5764 53156768.46

5765 104548719.19

6 rows selected.

Elapsed: 00:00:00.00

Execution Plan

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

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=1309 Bytes=24871)

1 0 SORT (GROUP BY ROLLUP) (Cost=5 Card=1309 Bytes=24871)

2 1 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=1309 Bytes=24871)

Statistics

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

0 recursive calls

0 db block gets

4 consistent gets

0 physical reads

0 redo size

557 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

6 rows processed

从上面的例子我们不难看出使用rollup函数,系统的sql语句更加简单,耗用的资源更少,从6个consistent gets降到4个consistent gets,如果基表很大的话,结果就可想而知了.

使用cube函数的介绍

为了介绍cube函数我们再来看看另外一个使用rollup的例子

06:53:00 SQL> select area_code,bill_month,sum(local_fare) local_fare

06:53:37 2 from t

06:53:38 3 group by rollup(area_code,bill_month)

06:53:49 4 /

AREA_CODE BILL_MONTH LOCAL_FARE

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

5761 200405 13060433.89

5761 200406 13318931.01

5761 200407 13710265.93

5761 200408 14135782.21

5761 54225413.04

5762 200405 12643792.11

5762 200406 12795060.65

5762 200407 13224298.12

5762 200408 13376468.72

5762 52039619.60

5763 200405 16649778.91

5763 200406 17120515.71

5763 200407 17487493.32

5763 200408 17928757.08

5763 69186545.02

5764 200405 12487791.94

5764 200406 13295187.67

5764 200407 13444093.76

5764 200408 13929695.09

5764 53156768.46

5765 200405 25057737.47

5765 200406 26058461.31

5765 200407 26301881.40

5765 200408 27130639.01

5765 104548719.19

333157065.31

26 rows selected.

Elapsed: 00:00:00.00

系统只是根据rollup的第一个参数area_code对结果集的数据做了汇总处理,而没有对bill_month做汇总分析处理,cube函数就是为了这个而设计的.

下面,让我们看看使用cube函数的结果

06:58:02 SQL> select area_code,bill_month,sum(local_fare) local_fare

06:58:30 2 from t

06:58:32 3 group by cube(area_code,bill_month)

06:58:42 4 order by area_code,bill_month nulls last

06:58:57 5 /

AREA_CODE BILL_MONTH LOCAL_FARE

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

5761 200405 13060.43

5761 200406 13318.93

5761 200407 13710.27

5761 200408 14135.78

5761 54225.41

5762 200405 12643.79

5762 200406 12795.06

5762 200407 13224.30

5762 200408 13376.47

5762 52039.62

5763 200405 16649.78

5763 200406 17120.52

5763 200407 17487.49

5763 200408 17928.76

5763 69186.54

5764 200405 12487.79

5764 200406 13295.19

5764 200407 13444.09

5764 200408 13929.69

5764 53156.77

5765 200405 25057.74

5765 200406 26058.46

5765 200407 26301.88

5765 200408 27130.64

5765 104548.72

200405 79899.53

200406 82588.15

200407 84168.03

200408 86501.34

333157.05

30 rows selected.

Elapsed: 00:00:00.01

可以看到,在cube函数的输出结果比使用rollup多出了几行统计数据.这就是cube函数根据bill_month做的汇总统计结果

rollup 和cube函数的再深入

从上面的结果中我们很容易发现,每个统计数据所对应的行都会出现null,

我们如何来区分到底是根据那个字段做的汇总呢,

这时候,oracle的grouping函数就粉墨登场了.

如果当前的汇总记录是利用该字段得出的,grouping函数就会返回1,否则返回0

1 select decode(grouping(area_code),1,'all area',to_char(area_code)) area_code,

2 decode(grouping(bill_month),1,'all month',bill_month) bill_month,

3 sum(local_fare) local_fare

4 from t

5 group by cube(area_code,bill_month)

6* order by area_code,bill_month nulls last

07:07:29 SQL> /

AREA_CODE BILL_MONTH LOCAL_FARE ---------- --------------- --------------

5761 200405 13060.43

5761 200406 13318.93

5761 200407 13710.27

5761 200408 14135.78

5761 all month 54225.41

5762 200405 12643.79

5762 200406 12795.06

5762 200407 13224.30

5762 200408 13376.47

5762 all month 52039.62

5763 200405 16649.78

5763 200406 17120.52

5763 200407 17487.49

5763 200408 17928.76

5763 all month 69186.54

5764 200405 12487.79

5764 200406 13295.19

5764 200407 13444.09

5764 200408 13929.69

5764 all month 53156.77

5765 200405 25057.74

5765 200406 26058.46

5765 200407 26301.88

5765 200408 27130.64

5765 all month 104548.72

all area 200405 79899.53

all area 200406 82588.15

all area 200407 84168.03

all area 200408 86501.34

all area all month 333157.05

30 rows selected.

Elapsed: 00:00:00.01

07:07:31 SQL>

可以看到,所有的空值现在都根据grouping函数做出了很好的区分,这样利用rollup,cube 和grouping函数,我们做数据统计的时候就可以轻松很多了.

rank函数的介绍

介绍完rollup和cube函数的使用,下面我们来看看rank系列函数的使用方法.

问题2.我想查出这几个月份中各个地区的总话费的排名.

为了将rank,dense_rank,row_number函数的差别显示出来,我们对已有的基础数据做一些修改,将5763的数据改成与5761的数据相同.

1 update t t1 set local_fare = (

2 select local_fare from t t2

3 where t1.bill_month = t2.bill_month

4 and https://www.sodocs.net/doc/0618496082.html,_type = https://www.sodocs.net/doc/0618496082.html,_type

5 and t2.area_code = '5761'

6* ) where area_code = '5763'

07:19:18 SQL> /

8 rows updated.

Elapsed: 00:00:00.01

我们先使用rank函数来计算各个地区的话费排名.

07:34:19 SQL> select area_code,sum(local_fare) local_fare,

07:35:25 2 rank() over (order by sum(local_fare) desc) fare_rank

07:35:44 3 from t

07:35:45 4 group by area_codee

07:35:50 5

AREA_CODE LOCAL_FARE FARE_RANK

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

5765 104548.72 1

5761 54225.41 2

5763 54225.41 2

5764 53156.77 4

5762 52039.62 5

Elapsed: 00:00:00.01

我们可以看到红色标注的地方出现了,跳位,排名3没有出现

下面我们再看看dense_rank查询的结果.

07:36:26 SQL> select area_code,sum(local_fare) local_fare,

07:39:16 2 dense_rank() over (order by sum(local_fare) desc ) fare_rank

07:39:39 3 from t

07:39:42 4 group by area_code

07:39:46 5 /

AREA_CODE LOCAL_FARE FARE_RANK

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

5765 104548.72 1

5761 54225.41 2

5763 54225.41 2

5764 53156.77 3 这是这里出现了第三名

5762 52039.62 4

Elapsed: 00:00:00.00

在这个例子中,出现了一个第三名,这就是rank和dense_rank的差别,

rank如果出现两个相同的数据,那么后面的数据就会直接跳过这个排名,而dense_rank则不会,差别更大的是,row_number哪怕是两个数据完全相同,排名也会不一样,这个特性在我们想找出对应每个条件的唯一记录的时候又很大用处

1 select area_code,sum(local_fare) local_fare,

2 row_number() over (order by sum(local_fare) desc ) fare_rank

3 from t

4* group by area_code

07:44:50 SQL> /

AREA_CODE LOCAL_FARE FARE_RANK

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

5765 104548.72 1

5761 54225.41 2

5763 54225.41 3

5764 53156.77 4

5762 52039.62 5

在row_nubmer函数中,我们发现,哪怕sum(local_fare)完全相同,我们还是得到了不一样排名,我们可以利用这个特性剔除数据库中的重复记录.

rank函数的介绍

a. 取出数据库中最后入网的n个用户

select user_id,tele_num,user_name,user_status,create_date from

(select user_id,tele_num,user_name,user_status,create_date,rank() over (order by create_date desc) add_rank from user_info)

where add_rank <= :n;

b.根据object_name删除数据库中的重复记录

create table t as select obj#,name from sys.obj$;

再insert into t1 select * from t1 数次.

delete from t1 where rowid in (

select row_id from (

select rowid row_id,row_number() over (partition by obj# order by rowid ) rn ) where rn <> 1

);

c. 取出各地区的话费收入在各个月份排名.

SQL> select bill_month,area_code,sum(local_fare) local_fare,

2 rank() over (partition by bill_month order by sum(local_fare) desc) area_rank

3 from t

4 group by bill_month,area_code

5 /

BILL_MONTH AREA_CODE LOCAL_FARE AREA_RANK

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

200405 5765 25057.74 1

200405 5761 13060.43 2

200405 5763 13060.43 2

200405 5762 12643.79 4

200405 5764 12487.79 5

200406 5765 26058.46 1

200406 5761 13318.93 2

200406 5763 13318.93 2

200406 5764 13295.19 4

200406 5762 12795.06 5

200407 5765 26301.88 1

200407 5761 13710.27 2

200407 5763 13710.27 2

200407 5764 13444.09 4

200407 5762 13224.30 5

200408 5765 27130.64 1

200408 5761 14135.78 2

200408 5763 14135.78 2

200408 5764 13929.69 4

200408 5762 13376.47 5

20 rows selected.

lag和lead函数介绍

取出每个月的上个月和下个月的话费总额

select area_code,bill_month, local_fare cur_local_fare,

lag(local_fare,2,0) over (partition by area_code order by bill_month ) pre_local_fare,

lag(local_fare,1,0) over (partition by area_code order by bill_month ) last_local_fare,

lead(local_fare,1,0) over (partition by area_code order by bill_month ) next_local_fare,

lead(local_fare,2,0) over (partition by area_code order by bill_month ) post_local_fare

from (

SELECT area_code,bill_month,sum(local_fare) local_fare

FROM t GROUP by area_code,bill_month

)

SQL> /

AREA_CODE BILL_MONTH CUR_LOCAL_FARE PRE_LOCAL_FARE LAST_LOCAL_FARE NEXT_LOCAL_FARE POST_LOCAL_FARE

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

5761 200405 13060.433 0 0 13318.93 13710.265

5761 200406 13318.93 0 13060.433 13710.265 14135.781

5761 200407 13710.265 13060.433 13318.93 14135.781 0

5761 200408 14135.781 13318.93 13710.265 0 0

5762 200405 12643.791 0 0 12795.06 13224.297

5762 200406 12795.06 0 12643.791 13224.297 13376.468

5762 200407 13224.297 12643.791 12795.06 13376.468 0

5762 200408 13376.468 12795.06 13224.297 0 0

5763 200405 13060.433 0 0 13318.93 13710.265

5763 200406 13318.93 0 13060.433 13710.265 14135.781

5763 200407 13710.265 13060.433 13318.93 14135.781 0

5763 200408 14135.781 13318.93 13710.265 0 0

5764 200405 12487.791 0 0 13295.187 13444.093

5764 200406 13295.187 0 12487.791 13444.093 13929.694

5764 200407 13444.093 12487.791 13295.187 13929.694 0

5764 200408 13929.694 13295.187 13444.093 0 0

5765 200405 25057.736 0 0 26058.46 26301.881

5765 200406 26058.46 0 25057.736 26301.881 27130.638

5765 200407 26301.881 25057.736 26058.46 27130.638 0

5765 200408 27130.638 26058.46 26301.881 0 0

20 rows selected.

利用lag和lead函数,我们可以在同一行中显示前n行的数据,也可以显示后n行的数据. sum,avg,max,min移动计算数据介绍

计算出各个连续3个月的通话费用的平均数

select area_code,bill_month, local_fare,

sum(local_fare)

over ( partition by area_code

order by to_number(bill_month)

range between 1 preceding and 1 following ) "3month_sum",

avg(local_fare)

over ( partition by area_code

order by to_number(bill_month)

range between 1 preceding and 1 following ) "3month_avg",

max(local_fare)

over ( partition by area_code

order by to_number(bill_month)

range between 1 preceding and 1 following ) "3month_max",

min(local_fare)

over ( partition by area_code

order by to_number(bill_month)

range between 1 preceding and 1 following ) "3month_min"

from (

select area_code,bill_month,sum(local_fare) local_fare

from t

group by area_code,bill_month

)

SQL> /

AREA_CODE BILL_MONTH LOCAL_FARE 3month_sum 3month_avg 3month_max 3month_min

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

5761 200405 13060.433 26379.363 13189.6815 13318.93 13060.433 5761 200406 13318.930 40089.628 13363.2093 13710.265 13060.433 5761 200407 13710.265 41164.976 13721.6587 14135.781 13318.93 40089.628 = 13060.433 + 13318.930 + 13710.265

13363.2093 = (13060.433 + 13318.930 + 13710.265) / 3

13710.265 = max(13060.433 + 13318.930 + 13710.265)

13060.433 = min(13060.433 + 13318.930 + 13710.265)

5761 200408 14135.781 27846.046 13923.023 14135.781 13710.265 5762 200405 12643.791 25438.851 12719.4255 12795.06 12643.791 5762 200406 12795.060 38663.148 12887.716 13224.297 12643.791 5762 200407 13224.297 39395.825 13131.9417 13376.468 12795.06 5762 200408 13376.468 26600.765 13300.3825 13376.468 13224.297 5763 200405 13060.433 26379.363 13189.6815 13318.93 13060.433 5763 200406 13318.930 40089.628 13363.2093 13710.265 13060.433 5763 200407 13710.265 41164.976 13721.6587 14135.781 13318.93 5763 200408 14135.781 27846.046 13923.023 14135.781 13710.265 5764 200405 12487.791 25782.978 12891.489 13295.187 12487.791 5764 200406 13295.187 39227.071 13075.6903 13444.093 12487.791 5764 200407 13444.093 40668.974 13556.3247 13929.694 13295.187 5764 200408 13929.694 27373.787 13686.8935 13929.694 13444.093 5765 200405 25057.736 51116.196 25558.098 26058.46 25057.736 5765 200406 26058.460 77418.077 25806.0257 26301.881 25057.736 5765 200407 26301.881 79490.979 26496.993 27130.638 26058.46 5765 200408 27130.638 53432.519 26716.2595 27130.638 26301.881

20 rows selected.

ratio_to_report函数的介绍

1 select bill_month,area_code,sum(local_fare) local_fare,

2 ratio_to_report(sum(local_fare)) over

3 ( partition by bill_month ) area_pct

4 from t

5* group by bill_month,area_code

SQL> break on bill_month skip 1

SQL> compute sum of local_fare on bill_month

SQL> compute sum of area_pct on bill_month

SQL> /

BILL_MONTH AREA_CODE LOCAL_FARE AREA_PCT

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

200405 5761 13060.433 .171149279 5762 12643.791 .165689431

5763 13060.433 .171149279

5764 12487.791 .163645143

5765 25057.736 .328366866

********** ---------------- ----------

sum 76310.184 1

200406 5761 13318.930 .169050772 5762 12795.060 .162401542

5763 13318.930 .169050772

5764 13295.187 .168749414

5765 26058.460 .330747499

********** ---------------- ----------

sum 78786.567 1

200407 5761 13710.265 .170545197 5762 13224.297 .164500127

5763 13710.265 .170545197

5764 13444.093 .167234221

5765 26301.881 .327175257

********** ---------------- ----------

sum 80390.801 1

200408 5761 14135.781 .170911147 5762 13376.468 .161730539

5763 14135.781 .170911147

5764 13929.694 .168419416

5765 27130.638 .328027751

********** ---------------- ----------

sum 82708.362 1

20 rows selected.

first,last函数使用介绍

取出每月通话费最高和最低的两个用户.

select bill_month,area_code,sum(local_fare) local_fare, first_value(area_code)

over (order by sum(local_fare) desc

rows unbounded preceding) firstval,

first_value(area_code)

over (order by sum(local_fare) asc

rows unbounded preceding) lastval

from t

group by bill_month,area_code

order by bill_month

SQL> /

BILL_MONTH AREA_CODE LOCAL_FARE FIRSTVAL LASTVAL ---------- --------- ---------------- --------------- ---------------

200405 5764 12487.791 5765 5764

200405 5762 12643.791 5765 5764

200405 5761 13060.433 5765 5764

200405 5765 25057.736 5765 5764

200405 5763 13060.433 5765 5764

200406 5762 12795.060 5765 5764

200406 5763 13318.930 5765 5764

200406 5764 13295.187 **** ****

200406 5765 26058.460 5765 5764

200406 5761 13318.930 5765 5764

200407 5762 13224.297 5765 5764

200407 5765 26301.881 5765 5764

200407 5761 13710.265 5765 5764

200407 5763 13710.265 5765 5764

200407 5764 13444.093 5765 5764

200408 5762 13376.468 5765 5764

200408 5764 13929.694 5765 5764

200408 5761 14135.781 5765 5764

200408 5765 27130.638 5765 5764

200408 5763 14135.781 5765 5764

20 rows selected.

Oracle中分析函数用法小结

Oracle中分析函数用法小结 一.分析函数适用场景: ○1需要对同样的数据进行不同级别的聚合操作 ○2需要在表内将多条数据和同一条数据进行多次的比较 ○3需要在排序完的结果集上进行额外的过滤操作 二.分析函数语法: FUNCTION_NAME(,...) OVER () 例: sum(sal) over (partition by deptno order by ename) new_alias sum就是函数名 (sal)是分析函数的参数,每个函数有0~3个参数,参数可以是表达式,例如:sum(sal+comm) over 是一个关键字,用于标识分析函数,否则查询分析器不能区别sum()聚集函数和sum()分析函数 partition by deptno 是可选的分区子句,如果不存在任何分区子句,则全部的结果集可看作一个单一的大区 order by ename 是可选的order by 子句,有些函数需要它,有些则不需要.依靠已排序数据的那些函数,如:用于访问结果集中前一行和后一行的LAG和LEAD,必须使用,其它函数,如AVG,则不需要.在使用了任何排序的开窗函数时,该子句是强制性的,它指定了在计算分析函数时一组内的数据是如何排序的. 1)FUNCTION子句 ORACLE提供了26个分析函数,按功能分5类 分析函数分类 等级(ranking)函数:用于寻找前N种查询 开窗(windowing)函数:用于计算不同的累计,如SUM,COUNT,AVG,MIN,MAX等,作用于数据的一个窗口上 例: sum(t.sal) over (order by t.deptno,t.ename) running_total, sum(t.sal) over (partition by t.deptno order by t.ename) department_total 制表(reporting)函数:与开窗函数同名,作用于一个分区或一组上的所有列 例: sum(t.sal) over () running_total2, sum(t.sal) over (partition by t.deptno) department_total2 制表函数与开窗函数的关键不同之处在于OVER语句上缺少一个ORDER BY子句! LAG,LEAD函数:这类函数允许在结果集中向前或向后检索值,为了避免数据的自连接,它们是非常有用的. VAR_POP,VAR_SAMP,STDEV_POPE及线性的衰减函数:计算任何未排序分区的统计值 2)PARTITION子句 按照表达式分区(就是分组),如果省略了分区子句,则全部的结果集被看作是一个单一的组 3)ORDER BY子句

Oracle 分析函数(Analytic Functions) 说明

Oracle 分析函数(Analytic Functions)说明一. Analytic Functions 说明 分析函数是oracle 8中引入的一个概念,为我们分析数据提供了一种简单高效的处理方式. 官方对分析函数的说明如下: Analytic functions compute an aggregate value based on a group of rows. They differ from aggregate functions in that they return multiple rows for each group. The groupof rows is called a window and is defined bythe analytic_clause. For each row, a sliding window of rows is defined.The window determines the range of rows used to perform the calculations forthe current row. Window sizes can be based on either a physical number of rowsor a logical interval such as time. Analytic functions are the last set of operations performed in a query except for thefinal ORDER BY clause. All joins and all WHERE, GROUP BY,and HAVING clauses are completed before the analytic functions areprocessed. Therefore, analytic functions can appear only in the select listor ORDER BY clause. Analytic functions are commonly used to compute cumulative, moving, centered, andreporting aggregates. From:Analytic Functions https://www.sodocs.net/doc/0618496082.html,/cd/E11882_01/server.112/e26088/functions004.htm#S QLRF06174 分析函数是对一组查询结果进行运算,然后获得结果,从这个意义上,分析函数非常类似于聚合函数(Aggregate Function)。区别是在调用分析函数时,后面加上了开窗子句over()。 聚合函数是对一个查询结果中的每个分组进行运算,并且对每个分组产生一个运算结果。分析函数也是对一个查询结果中的每个分组进行运算,但每个分组对应的结果可以有多个。产生这个不同的原因是分析函数中有一个窗口的概念,一个窗口对应于一个分组中的若干行,分析函数每次对一个窗口进行运算。运算时窗口在查询结果或分组中从顶到底移动,对每一行数据生成一个窗口。 Oracle 聚合函数(Aggregate Functions)说明 https://www.sodocs.net/doc/0618496082.html,/tianlesoftware/article/details/7057249

oracle比较decode(case when) 、4种去重---和去重中的统计函数

oracle比较decode/case when 、4种去重和去重中的统计函数 一:decode 和case when decode (expression, search_1, result_1, search_2, result_2, ...., search_n, result_n, default) decode函数比较表达式和搜索字,如果匹配,返回结果;如果不匹配,返回default值;如果未定义default值,则返回空值。 select username,decode(lock_date,null,'unlocked','locked') status from t; ----------------如果lock_date是null就返回unlocked 如果不是null就返回locked select username,decode(lock_date,null,'unlocked') status from t; ----------------如果lock_date是null就返回unlocked 否则是空(因为没有定义) 例如有个学生表...... 行转列------- create table score2( name varchar2(10), Language number(3), Math number(3), English number(3)); insert into score2 values('Zhang',80,67,95); insert into score2 values('Li',79,84,62); insert into score2(name,Language) values('Chen',88); commit; Select * from score2; 显示成报表的格式....... select name, sum(decode(subject,'Language', grade,0)) "Language", sum(decode(subject,'Math', grade,0)) "Math", sum(decode(subject,'English', grade,0)) "English" from score group by name; NAME Language Math English -------------------- ---------- ---------- ---------- Zhang 80 92 76 Wang 73 0 0 Li 81 95 50 第二列,如果subject='Language',那么就显示成绩,否则显示为0 第三列,如果subject='Math',那么就显示成绩,否则显示为0 第四列,如果subject='English',那么就显示成绩,否则显示为0 Case when Case [selector] ---selector可以不设置 When id=1 THEN ‘id是1’; ELSE ‘没有id值’; END CASE; ---->如果ID=1 就显示id是1 否则显示没有id值 ~~~~~上面用case when显示................. select https://www.sodocs.net/doc/0618496082.html,, sum( case when t.subject = 'Language' then t.grade else 0 end ) dd, sum( case when t.subject = 'Math' then t.grade else 0 end ) Math,

ORACLE排序与分析函数

--已知:两种排名方式(分区和不分区):使用和不使用partition --两种计算方式(连续,不连续),对应函数:dense_rank,rank 语法: rank()over(order by排序字段顺序) rank()over(partition by分组字段order by排序字段顺序) 1.顺序:asc|desc名次与业务相关: 示例:找求优秀学员:成绩:降序迟到次数:升序 2.分区字段:根据什么字段进行分区。 问题:分区与分组有什么区别? ·分区只是将原始数据进行名次排列(记录数不变), ·分组是对原始数据进行聚合统计(记录数变少,每组返回一条),注意:聚合。rank()与dense_rank():非连续排名与连续排名(都是简单排名) ·查询原始数据:学号,姓名,科目名,成绩 select*from t_score; S_ID S_NAME SUB_NAME SCORE 1张三语文80.00 2李四数学80.00 1张三数学0.00 2李四语文50.00 3张三丰语文10.00 3张三丰数学 3张三丰体育120.00 4杨过JAVA90.00 5mike c++80.00 3张三丰Oracle0.00 4杨过Oracle77.00 2李四Oracle77.00 ·查询各学生科目为Oracle排名(简单排名) select sc.s_id,sc.s_name,sub_name,sc.score,rank()over(order by score desc)名次from t_score sc where sub_name='Oracle'; S_ID S_NAME SUB_NAME SCORE名次 4杨过Oracle77.001 2李四Oracle77.001 3张三丰Oracle0.003 ·对比:rank()与dense_rank():非连续排名与连续排名(都是简单排名) S_ID S_NAME SUB_NAME SCORE名次

Oracle分析函数sum over介绍

分析函数sum over() 介绍 报送单位:审核人: 类型:业务应用 关键字:分析函数 1、引言 运维中,常常需要通过SQL语句对单行数据进行查询,同时又需要对结果集进行汇总,通常的方法是通过两个SQL语句分别进行查询汇总,这样效率低下。 2、现象描述 本节介绍一种ORACLE提供的全新的函数sum over(),该类函数称为分析函数,这类函数功能强大,可以通过一个SQL语句对数据进行遍历的同时又进行汇总,而且一张表只进行一次扫描,极大地提高SQL的执行效率。 3、处理过程 语法: FUNCTION_NAME(,,...) OVER() NAME:可以是SUM,AVG,MAX,MIN,COUNT等其它,这些函数单独使用称为聚集函数,与OVER子句一起使用使称为分析函数。在当分析函数使用时,SQL语句中不需要使用GROUP BY子句。

执行计划: 下图说明分析函数只对表进行一次扫描 4、举例说明 下面分别举例来说明分析函数的使用,原始数据如下表

示例1:查询单行数据同时对所有数据工资进行汇总求和 示例2:查询所有数据,同时对第各部门工资进行汇总,汇总范围取值为第一行所在部门至当前部门所有数据。

示例3:查询所有数据,并且每一行汇总值按ENAME排序后取第一行至当前行ENAME所在行。 示例4:查询所有数据,并且每一行汇总值按EMPNO排序后取第一行至当前行EMPNO所在行

示例5:查询所有数据,同时每行对各部门分别进行按EMPNO排序后从各组第一行至当前行汇总求和。 示例6:查询所有数据,同时每行对从当前上两行数据范围的工资进行汇总求和。 示例7:查询所有数据,同时每行对从当前向前一行数据向后两行数据范围的工资进行汇总求和。

Oracle分析函数

Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是 对于每个组返回多行,而聚合函数对于每个组只返回一行。 一、开窗函数 开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化。 例如: 1)over(order by salary)按照salary排序进行累计,order by是个默认的开窗函数 2)over(partition by department_id)按照部门分区 3)over(order by salary range between 50 preceding and 150 following) 每行对应的数据窗口是之前行幅度值不超过50,之后行幅度值不超过150 4)over(order by salary rows between 50 preceding and 150 following) 每行对应的数据窗口是之前50行,之后150行 5)over(order by salary rows between unbounded preceding and unbounded following) 每行对应的数据窗口是从第一行到最后一行,等效: 6) over(order by salary range between unbounded preceding and unbounded following) 其中: 第一行是unbounded preceding 当前行是current row 最后一行是unbounded following 二、分析函数的概念 分析函数是在整个SQL查询结束后(SQL语句中的ORDER BY的执行比较特殊)再进行的操作, 也就是说 SQL语句中的ORDER BY也会影响分析函数的执行结果。 分析函数中包含三个分析子句:分组(Partition By), 排序(Order By), 窗口(Window) 当省略窗口子句时: 1) 如果存在Order By则默认的窗口是unbounded preceding and current row 2) 如果同时省略Order By则默认的窗口是unbounded preceding and unbounded following 如果省略分组,则把全部记录当成一个组 a) 如果SQL语句中的Order By满足分析函数分析时要求的排序,那么SQL语句中的排序将先执行,分析 函数分析时就不必再排序 b) 如果SQL语句中的Order By不满足分析函数分析时要求的排序,那么SQL语句中的排序将最后在分 析函数分析结束后执行排序 三、分析函数 1)AVG

Oracle自定义聚合函数-分析函数

自定义聚合函数,分析函数 --from GTA Aaron 最近做一数据项目要用到连乘的功能,而Oracle数据库里没有这样的预定义聚合函数,当然利用数据库已有的函数进行数学运算也可以达到这个功能,如: selectexp(sum(ln(field_name))) from table_name; 不过今天的重点不是讲这个数学公式,而是如何自己创建聚合函数,实现自己想要的功能。很幸运Oracle 允许用户自定义聚合函数,提供了相关接口,LZ研究了下,留贴共享。 首先介绍聚合函数接口: 用户可以通过实现Oracle的Extensibility Framework中的ODCIAggregate interface 来创建自定义聚合函数,而且自定义的聚合函数跟内建的聚合函数用法上没有差别。 通过实现ODCIAggregaterountines来创建自定义的聚合函数。可以通过定义一个对象类型(Object Type),然后在这个类型内部实现ODCIAggregate 接口函数(routines),可以用任何一种Oracle支持的语言来实现这些接口函数,比如C/C++, JAVA, PL/SQL等。在这个Object Type定义之后,相应的接口函数也都在该Object Type Body内部实现之后,就可以通过CREATE FUNCTION语句来创建自定义的聚合函数了。 每个自定义的聚合函数需要实现4个ODCIAggregate 接口函数,这些函数定义了任何一个聚合函数内部需要实现的操作: 1. 自定义聚合函数初始化操作,从这儿开始一个聚合函数。初始化的聚合环境(aggregation context)会以对象实例(object type instance)传回给oracle. static function ODCIAggregateInitialize(varIN OUTagg_type ) return number 2. 自定义聚合函数,最主要的步骤,这个函数定义我们的聚合函数具体做什么操作,self 为 当前聚合函数的指针,用来与前面的计算结果进行关联。这个函数用来遍历需要处理的

Oracle常用函数及使用案例(珍藏版)

Oracle常用函数及使用案例(珍藏版) 一:sql函数: lower(char):将字符串转化为小写的格式。 upper(char):将字符串转化为大写的格式。 length(char):返回字符串的长度。 substr(char,m,n):取字符串的字串。 案例1.将所有员工的名字按小写的方式显示 select lower(ename),sal from emp; 案例2.将所有员工的名字按大写的方式显示。 select upper(ename),sal from emp; 案例3.显示正好为五个字符的的员工的姓名。 select * from emp where length(ename)=5; 案例4.显示所有员工姓名的前三个字符。 select substr(ename,1,3) from emp;//从名字的第一个字符开始取,向后取三个字符。 案例5.以首字母为大写的方式显示所有员工的姓名。 (1)首字母大写:select upper(substr(ename,1,1)) from emp; (2)完成后面字母小写。select lower(substr(ename,2,length(ename)-1)) from emp; (3)合并select upper(substr(ename,1,1))||lower(substr(ename,2,length(ename)-1)) from emp; 案例6.以首字母为小写的方式显示所有员工的姓名。(需要有较高的灵活度,细心分析和清晰思路) (1)首字母小写:select upper(substr(ename,1,1)) from emp; (2)完成后面字母大写。select lower(substr(ename,2,length(ename)-1)) from emp; (3)合并select lower(substr(ename,1,1))||upper(substr(ename,2,length(ename)-1)) from emp; 案例7.函数(替换):replace(char1,search_string,replace_string); 显示所有员工的姓名,用“我要替换A”替代所有“A”。 select replace(ename,'A','我是老鼠')from emp; 案例8.以首字母为小写的方式显示所有员工的姓名。 select replace(ename,substr(ename,1,1),lower(substr(ename,1,1)))from emp; 案例9.以首字母为大写的方式显示所有员工的姓名。 Select replace(ename,substr(ename,2,length(ename)-1),lower(substr(ename,2,length(ename) -1)))from emp; 二:数学函数:(在财务中用的比较多) ronud(sal)用于四舍五默认取整; ronud(sal,1)用于四舍五留一位小数。 trunc(sal)取整,忽略小数。截去小数部分。 trunc(sal,1)截取;小数点留一位,之后的右边的省去。 trunc(sal,-1)截取;只留整数,个位数取零。 floor(sal)向下最接近取整;比如1.1值为1.

oracle高级分析函数使用实例

oracle高级分析函数使用实例 2014年11月26日10:26:55 ?标签: ?oracle ?1744 ORACLE的分析函数,发现大家写SQL的时候有些功能写的比较麻烦或者不知道复杂的功能怎么通过SQL实现,ORACLE自带的分析函数有很多相应的功能: 它是Oracle分析函数专门针对类似于"经营总额"、"找出一组中的百分之多少" 或"计算排名前几位"等问题设计的。 分析函数运行效率高,使用方便。 分析函数是基于一组行来计算的。这不同于聚集函数且广泛应用于OLAP环境中。 Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是 对于每个组返回多行,而聚合函数对于每个组只返回一行。 语法: (,,...) over( ) 其中: 1 over是关键字,用于标识分析函数。 2 是指定的分析函数的名字。Oracle分析函数很多。 3 为参数,分析函数可以选取0-3个参数。 4 分区子句的格式为: partition by[,value_expr]... 关键字partition by子句根据由分区表达式的条件逻辑地将单个结果集分成N

组。这里的"分区partition"和"组group" 都是同义词。 5 排序子句order-by-clause指定数据是如何存在分区内的。其格式为:order[siblings]by{expr|position|c_alias}[asc|desc][nulls first|nulls last] 其中: (1)asc|desc:指定了排列顺序。 (2)nulls first|nulls last:指定了包含空值的返回行应出现在有序序列中的第一个或最后一个位置。 6窗口子句windowing-clause 给出一个固定的或变化的数据窗口方法,分析函数将对这些数据进行操作。在一组基于任意变化或固定的窗口中, 可用该子句让分析函数计算出它的值。 格式: {rows|range} {between {unbounded preceding|current row |{preceding|following} }and {unbounded preceding|current row |{preceding|following} }|{unbounded preceding|current row |{preceding|following }} (1)rows|range:此关键字定义了一个window。 (2)between...and...:为窗品指一个起点和终点。 (3)unbounded preceding:指明窗口是从分区(partition)的第一行开始。 (4)current row:指明窗口是从当前行开始。 create table emp( deptno varchar2(20),--部门编码 ename varchar2(20),--人名 sal number(10));--工资 insert into emp values('10','andy1',2000); insert into emp values('10','andy2',3000); insert into emp values('10','andy3',2000); insert into emp values('20','leno1',4000); insert into emp values('20','leno2',8000);

Oracle高级查询总结

高级查询总结 A.层次查询:start with……connec by prior…….. select lpad(' ',3*level)||ename,job,level from emp start with mgr is null connect by prior empno=mgr; 从根结点向下查,lpad()为左添加,level为第几层,prior为查找的方向;此句若省掉start with….则表示要遍历整个树型结构;若出现level,则后面一定要跟connect by B.交叉报表(case when then end 与decode()) select ename,case when sal>=1500then sal*1.01 else sal*1.1 end工资 from emp; select姓名, max(case课程when'语文'then分数end) 语文, max(case课程when'数学'then分数end) 数学, max(case课程when'历史'then分数end) 历史 from学生group by姓名;------(交叉报表与函数一起使用) select ename,sum(decode(sal,'sal',comm,null)) 奖金from emp group by ename;--可实现分支 decode(条件,(值),(返回值),…………,(默认值)) 部门 select sal,decode(sign(sal-1500),-1,1.1*sal,0,1.1*sal,1,1.05*sal) from emp; C.连接查询 1.等值: select * from emp,dept where emp.deptno(+)=dept.deptno; ‘+’在左则以右表为主,反之亦然 2.非等值:where的运算符不是等号 3.自然连接: select * from emp natural join dept 4.99乘法: select * from emp e full join dept d using (deptno) where deptno=10; --where必须放在using(on)的后面 D集合查询: 1.A Union B:消除重复行,有all则可以重复,默认第一列升序select ename,sal from deptno=20 union select ename,sal from job=’CLERK’; 2.A intersect B:A与B的交集 select ename,sal from deptno=20 intersect select ename,sal from job=’CLERK’; 3.A minus B:在A中减去既属于A又属于B的一部分

Oracle 分析函数

--每一个值占总数的百分比 SELECT x, y, z,round(z/sum(z) over()*100,2)||'%' propn , sum(z) over() sum FROM t1; --每一个值占分组的百分比 SELECT x, y, z,round(z/sum(z) over(partition by x)*100,2)||'%' propn , sum(z) over(partition by x) sum FROM t1; --以x分区,按y排序累计取和 SELECT x, y, z, sum(z) over(partition by x order by y desc) sum FROM t1; --以x分区,按z降序,每个分区取前两个 select * from (select x, y, z, s, dense_rank() over(partition by x order by z desc) r1, rank() over(partition by x order by z desc) r2, count(*) over(partition by x order by z desc, y range unbounded preceding) r3 from (SELECT x, y, z, sum(z) over(partition by x) s FROM t1 order by 4 desc, z desc)) where r3 < 3 order by z desc, x /* 语法: function_name(,,...) over() 函数名(参数) over关键字( :over关键字用于区分普通聚集函数和分析函数,必选 partition子句:将结果集分区分组,当分区变化时重新计数 ORDER BY子句:数据在分区内是如何存储的,会直接影响一些分析函数 windowing子句:一个定义变化或固定的数据窗口方法,用于分析函数计数 range窗口:根据where条件将行集中到一起,如range 5 preceding,产生一个滑动窗口,在分区内拥有所有当前行以前的5行集合,只能用于数值和日期,order by只能有一列 order by sal range 1000 preceding row窗口:是物理单元,包括在窗口中的行的物理数 order by row 5 preceding 包含6行,当前行以及前面的5行,“前面”是指order by后的 ) */ select deptno, empno,

Oracle分析函数与分组关键字的用法

Oracle分析函数与分组关键字的用法 以下是我以前工作中做报表常用的几个函数,在此分享一下,希望对大家有帮助。 (一)分析函数 ●row_number Purpose ROW_NUMBER is an analytic function. It assigns a unique number to each row to which it is applied (either each row in the partition or each row returned by the query), in the ordered sequence of rows specified in the order_by_clause, beginning with 1. You cannot use ROW_NUMBER or any other analytic function for expr. That is, you can use other built-in function expressions for expr, but you cannot nest analytic functions. 按部门分组后根据工资排序,序号rn特征:连续、无并列 select t.*, row_number() over(partition by t.deptno order by sal desc) rn from emp t; ●rank

Purpose RANK calculates the rank of a value in a group of values. Rows with equal values for the ranking criteria receive the same rank. Oracle then adds the number of tied rows to the tied rank to calculate the next rank. Therefore, the ranks may not be consecutive numbers. ? As an aggregate function, RANK calculates the rank of a hypothetical row identified by the arguments of the function with respect to a given sort specification. The arguments of the function must all evaluate to constant expressions within each aggregate group, because they identify a single row within each group. The constant argument expressions and the expressions in the ORDER BY clause of the aggregate match by position. Therefore, the number of arguments must be the same and their types must be compatible. As an analytic function, RANK computes the rank of each row returned from a query with respect to the other rows returned by the query, based on the values of the value_exprs in the order_by_clause. 按部门分组后根据工资排序,序号rn特征:不连续、有并列 select t.*, rank() over(partition by t.deptno order by sal desc) rn from emp t; dense_rank

oracle之分析函数over及开窗函数

oracle之分析函数over及开窗函数 一:分析函数over Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是对于每个组返回多行,而聚合函数对于每个组只返回一行。 统计各班成绩第一名的同学信息 NAME CLASS S ----- ----- ---------------------- fda 1 80 ffd 1 78 dss 1 95 cfe 2 74 gds 2 92 gf 3 99 ddd 3 99 adf 3 45 asdf 3 55 3dd 3 78 通过: -- select * from ( select name,class,s,rank()over(partition by class order by s desc) mm from t2 ) where mm=1 ---- 得到结果:

NAME CLASS S MM ----- ----- ---------------------- ---------------------- dss 1 95 1 gds 2 92 1 gf 3 99 1 ddd 3 99 1 注意: 1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一, row_number()只返回一个结果 2.rank()和dense_rank()的区别是: --rank()是跳跃排序,有两个第二名时接下来就是第四名 --dense_rank()l是连续排序,有两个第二名时仍然跟着第三名 二:开窗函数 开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下: 1: over(order by salary)按照salary排序进行累计,order by是个默认的开窗函数over(partition by deptno)按照部门分区 2: over(order by salary range between 5 preceding and 5 following) 每行对应的数据窗口是之前行幅度值不超过5,之后行幅度值不超过5 例如:对于以下列 aa 1 2 2

Oracle统计学函数-大数据分析介绍

SQL Statistical Functions Make Big Data + Analytics Simple Charlie Berger, MS Engineering, MBA Sr. Director Product Management, Data Mining and Advanced Analytics charlie.berger@https://www.sodocs.net/doc/0618496082.html, https://www.sodocs.net/doc/0618496082.html,/CharlieDataMine

Data, data everywhere Data Analysis platforms requirements: ?Be extremely powerful and handle large data volumes ?Be easy to learn ?Be highly automated & enable deployment Growth of Data Exponentially Greater than Growth of Data Analysts! https://www.sodocs.net/doc/0618496082.html,/more-data-than-analysts-the-real-big-data-problem/

Analytics + Data Warehouse + Hadoop ?Platform Sprawl –More Duplicated Data –More Data Movement Latency –More Security challenges –More Duplicated Storage –More Duplicated Backups –More Duplicated Systems –More Space and Power

Oracle分析函数使用的总结(学练结合)

Oracle分析函数使用总结 1.使用评级函数 评级函数(ranking function)用于计算等级、百分点、n分片等等,下面是几个常用到的评级函数:RANK():返回数据项在分组中的排名。特点:在排名相等的情况下会在名次中留下空位DENSE_RANK():与RANK不同的是它在排名相等的情况下不会在名次中留下空位 CUME_DIST():返回特定值相对于一组值的位置:他是“cumulative distribution”(累积分布)的简写PERCENT_RANK():返回某个值相对于一组值的百分比排名 NTILE():返回n分片后的值,比如三分片、四分片等等 ROW_NUMBER():为每一条分组纪录返回一个数字 下面我们分别举例来说明这些函数的使用 1)RANK()与DENSE-RANK() 首先显示下我们的源表数据的结构及部分数据: SQL> desc all_sales; 名称是否为空? 类型 ----------------------------------------- -------- ----------- YEAR NOT NULL NUMBER(38) MONTH NOT NULL NUMBER(38) PRD_TYPE_ID NOT NULL NUMBER(38) EMP_ID NOT NULL NUMBER(38) AMOUNT NUMBER(8,2) SQL> select * from all_sales where rownum<11; YEAR MONTH PRD_TYPE_ID EMP_ID AMOUNT ---------- ---------- ----------- ---------- ---------- 2003 1 1 21 10034.84 2003 2 1 21 15144.65 2003 3 1 21 20137.83 2003 4 1 21 25057.45 2003 5 1 21 17214.56 2003 6 1 21 15564.64 2003 7 1 21 12654.84 2003 8 1 21 17434.82 2003 9 1 21 19854.57 2003 10 1 21 21754.19 已选择10行。 好接下来我们将举例来说明上述函数的使用:首先是RANK()与DENSE-RANK()的使用:SQL> select 2 prd_type_id,sum(amount), 3 RANK() OVER (ORDER BY SUM(amount) DESC) AS rank, 4 DENSE_RANK() OVER (ORDER BY SUM(amount) DESC) AS dense_rank

相关主题