分组函数group by 和分析函数over()

    今天在进行生成库字段初始化的时候遇到这样一个需求:web

按照在客户交易信息表中   按照客户的帐户类型分组,并按照日期排序,最后按照分组排序后的顺序给一个temp6字段进行顺序赋值。sql

    小弟本来打算使用group by进行先分组,在排序最后查出rownum  id  在进行赋值就ok   。但试了不少方法,group by返回的都只有一行。后来找到了一个神器。over()分析函数。oracle

   over(partition by xx列)函数  能够对该列进行分组  并返回多行(有几行就返回几行),最后的函数的概括为:函数

select t.*,row_number() over(partition by t.account_id order by t.create_time) row_number from me_cus_trade_info t ;spa

这样就实现了  按帐户id进行分组,按建立时间排序, 返回全部,和row_number(这个是别名)。3d

将查出的row_number的值插入到temp6中  的sql有些绕,,不过也参照大神的写出来了orm

update me_cus_trade_info ct
   set ct.temp6 =
       (select mi.row_number
          from (select t.id,
                       t.account_id,
                       t.temp6,
                       row_number() over(partition by t.account_id order by t.create_time) row_number
                  from me_cus_trade_info t) mi
         where ct.id = mi.id)排序

上面的语句是针对全表进行的,要当心执行,,若是要个别执行须要加一些条件好比:ci

 where exists (select 1 from me_cus_trade_info t where ct.id = t.id)it

 

固然over()分析函数的用法功能不止这些:

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

一:分析函数over
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不一样之处是
对于每一个组返回多行,而聚合函数对于每一个组只返回一行。
下面经过几个例子来讲明其应用。
1:统计某商店的营业额。
date sale
1 20
2 15
3 14
4 18
5 30
规则:按天统计:天天都统计前面几天的总额
select t.* ,sum(sale) over(order by date) sum from example t
获得的结果:
DATE SALE SUM
—– ——– ——
1 20 20 –1天
2 15 35 –1天+2天
3 14 49 –1天+2天+3天
4 18 67 .
5 30 97 .
2:统计各班成绩第一名的同窗信息
NAME CLASS S
—– —– ————-
fda 1 80
ffd 1 78
dss 1 95
cfe 2 74
gds 2 92
gf 3 99
ddd 3 99
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是连续排序,有两个第二名时仍然跟着第三名
3.分类统计 (并显示信息)
A B C
— – ——
m a 2
n a 3
m a 2
n b 2
n b 1
x b 3
x b 2
x b 4
h b 3
select a,c,sum(c)over(partition by a) from t2
获得结果:
A B C SUM(C)OVER(PARTITIONBYA)
— – ——- ————————
h b 3 3
m a 2 4
m a 2 4
n a 3 6
n b 2 6
n b 1 6
x b 3 9
x b 2 9
x b 4 9
若是用sum,group by 则只能获得
A SUM(C)
— ———————-
h 3
m 4
n 6
x 9
没法获得B列值
—将B栏位值相同的对应的C 栏位值加总,数据:
A B C
1 1 1
1 2 2
1 3 3
2 2 5
3 4 6
select a,b,c, SUM(C) OVER (PARTITION BY B) C_Sum
from test
查询结果:
A B C C_SUM
1 1 1 1
1 2 2 7
2 2 5 7
1 3 3 3
3 4 6 6
—若是不须要以某个栏位的值分割,那就要用null,这样就会将C的栏位值sum放在每行后面,也能够直接空着,不须要填写,如over()
select a,b,c, SUM(C) OVER (PARTITION BY null) C_Sum
from test
A B C C_SUM
1 1 1 17
1 2 2 17
1 3 3 17
2 2 5 17
3 4 6 17
求我的工资占部门工资的百分比
NAME DEPT SAL
———- —- —–
a 10 2000
b 10 3000
c 10 5000
d 20 4000
SQL> select name,dept,sal,sal*100/sum(sal) over(partition by dept) percent from salary;
NAME DEPT SAL PERCENT
———- —- —– ———-
a 10 2000 20
b 10 3000 30
c 10 5000 50
d 20 4000 100
二:开窗函数
开窗函数指定了分析函数工做的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例以下:
over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
over(partition by deptno)按照部门分区
over(order by salary range between 5 preceding and 5 following)
每行对应的数据窗口是以前行幅度值不超过5,以后行幅度值不超过5
例如:对于如下列
aa
1
2
2
2
3
4
5
6
7
9
sum(aa)over(order by aa range between 2 preceding and 2 following)
得出的结果是
AA SUM
———————- ———————–
1 10
2 14
2 14
2 14
3 18
4 18
5 22
6 18
7 22
9 9
就是说,对于aa=5的一行 ,sum为 5-1<=aa<=5+2 的和
对于aa=2来讲 ,sum=1+2+2+2+3+4=14 ;
又如 对于aa=9 ,9-1<=aa<=9+2 只有9一个数,因此sum=9 ;
over(order by salary rows between 2 preceding and 4 following)
每行对应的数据窗口是以前2行,以后4行
下面三条语句等效:
over(order by salary rows between unbounded preceding and unbounded following)
每行对应的数据窗口是从第一行到最后一行,等效:
over(order by salary range between unbounded preceding and unbounded following)
等效over(partition by null)
语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再为降序之后的没条xlh记录返回一个序号。
示例:
xlh row_num
1700 1
1500 2
1085 3
710 4
row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的惟一的)
实例:
create table employee (empid int ,deptid int ,salary decimal(10,2))
insert into employee values(1,10,5500.00)
insert into employee values(2,10,4500.00)
insert into employee values(3,20,1900.00)
insert into employee values(4,20,4800.00)
insert into employee values(5,40,6500.00)
insert into employee values(6,40,14500.00)
insert into employee values(7,40,44500.00)
insert into employee values(8,50,6500.00)
insert into employee values(9,50,7500.00)
数据显示为
empid deptid salary
———– ———– ——————-
1 10 5500.00
2 10 4500.00
3 20 1900.00
4 20 4800.00
5 40 6500.00
6 40 14500.00
7 40 44500.00
8 50 6500.00
9 50 7500.00
需求:根据部门分组,显示每一个部门的工资等级
预期结果:
empid deptid salary rank
———– ———– ————— ———-
1 10 5500.00 1
2 10 4500.00 2
4 20 4800.00 1
3 20 1900.00 2
7 40 44500.00 1
6 40 14500.00 2
5 40 6500.00 3
9 50 7500.00 1
8 50 6500.00 2

SQL脚本:SELECT *, Row_Number() OVER (partition by deptid ORDER BY salary desc) rank FROM employee

相关文章
相关标签/搜索