1、函数介绍

over(order by xxx) 按照xxx字段排序进行累计,order by是一个默认的开窗函数;

over (partition by xxx,yyy)按照 xxx,yyy 字段分区;

over (partition by xxx order by yyy)按照 xxx 字段分区,并按照yyy字段排序进行累计。

2、测试表结构以及数据

声明:以下数据均为测试数据。

测试表 test_2021 的表结构如下:

名称

类型

可为空

注释

YEAR_NAME

VARCHAR2(19)

Y

年份名称

MONTH_NAME

VARCHAR2(11)

Y

月份名称

POST_CODE

VARCHAR2(52)

Y

岗位编码

POST_NAME

VARCHAR2(300)

Y

岗位名称

TESTTYPE_CODE

CHAR(2)

Y

试验类型编码

TESTTYPE_NAME

CHAR(6)

Y

试验类型名称

COST_AMT

NUMBER

Y

产值

测试表 test_2021的部分数据如下:

年份名称

月份名称

岗位编码

岗位名称

试验类型编码

试验类型名称

产值

2017年

11月

7

电连接器器件检测岗

2

复验

460

2018年

02月

7

电连接器器件检测岗

1

筛选

356

2018年

04月

7

电连接器器件检测岗

1

筛选

980

2019年

12月

7

电连接器器件检测岗

1

筛选

366

2019年

05月

7

电连接器器件检测岗

1

筛选

716

2020年

07月

7

电连接器器件检测岗

1

筛选

681

2017年

12月

7

电连接器器件检测岗

1

筛选

325

2019年

02月

8

机电元件检测岗

2

复验

274

2018年

06月

8

机电元件检测岗

1

筛选

876

2019年

07月

8

机电元件检测岗

2

复验

349

2019年

12月

8

机电元件检测岗

2

复验

292

2019年

08月

8

机电元件检测岗

1

筛选

837

2020年

02月

8

机电元件检测岗

2

复验

250

2020年

03月

8

机电元件检测岗

1

筛选

470

2020年

09月

8

机电元件检测岗

1

筛选

453

2019年

05月

8

机电元件检测岗

1

筛选

348

2018年

01月

8

机电元件检测岗

1

筛选

707

2020年

02月

8

机电元件检测岗

1

筛选

244

2018年

10月

8

机电元件检测岗

1

筛选

45

3、测试SQL
3.1、测试 over (partition by xxx,yyy)按照xxx,yyy字段分区

需求:按照岗位编码,岗位名称,试验类型编码,试验类型名称以及年份进行分区求产值的累计和,求出了同一年份同一岗位同一试验类型的不同月份的产值的和

select
year_name,--年份名称
month_name,--月份名称
post_code,--岗位编码
post_name,--岗位名称
testtype_code,--试验类型编码
testtype_name,--试验类型名称
cost_amt,--产值
sum(cost_amt) over (partition by post_code,post_name,testtype_code,testtype_name,year_name) as leiji_amt--累计产值
from test_2021
where year_name = '2016年'
order by year_name,month_name

执行结果如下:

年份名称

月份名称

岗位编码

岗位名称

试验类型编码

试验类型名称

产值

累计产值

2016年

11月

4

阻容元件检测岗

2

复验

391

1261

2016年

11月

6

微波器件检测岗

2

复验

802

824

2016年

11月

4

阻容元件检测岗

1

筛选

884

1098

2016年

11月

7

电连接器器件检测岗

2

复验

57

464

2016年

11月

5

分立器件检测岗

2

复验

795

871

2016年

11月

8

机电元件检测岗

2

复验

874

1362

2016年

11月

6

微波器件检测岗

1

筛选

388

1021

2016年

11月

8

机电元件检测岗

1

筛选

640

1457

2016年

11月

5

分立器件检测岗

1

筛选

874

1723

2016年

12月

4

阻容元件检测岗

1

筛选

214

1098

2016年

12月

7

电连接器器件检测岗

2

复验

407

464

2016年

12月

8

机电元件检测岗

2

复验

488

1362

2016年

12月

8

机电元件检测岗

1

筛选

817

1457

2016年

12月

6

微波器件检测岗

2

复验

22

824

2016年

12月

6

微波器件检测岗

1

筛选

633

1021

2016年

12月

5

分立器件检测岗

2

复验

76

871

2016年

12月

4

阻容元件检测岗

2

复验

870

1261

2016年

12月

5

分立器件检测岗

1

筛选

849

1723

我们将以上数据按累计产值排序以后,会更直观的看出同一年份同一岗位同一试验类型的不同月份的产值的和

比如累计产值为464的值,就是2016年 电连接器器件检测岗 复验 这种试验11月份和12月份的和。

年份名称

月份名称

岗位编码

岗位名称

试验类型编码

试验类型名称

产值

累计产值

2016年

11月

7

电连接器器件检测岗

2

复验

57

464

2016年

12月

7

电连接器器件检测岗

2

复验

407

464

2016年

12月

6

微波器件检测岗

2

复验

22

824

2016年

11月

6

微波器件检测岗

2

复验

802

824

2016年

12月

5

分立器件检测岗

2

复验

76

871

2016年

11月

5

分立器件检测岗

2

复验

795

871

2016年

12月

6

微波器件检测岗

1

筛选

633

1021

2016年

11月

6

微波器件检测岗

1

筛选

388

1021

2016年

11月

4

阻容元件检测岗

1

筛选

884

1098

2016年

12月

4

阻容元件检测岗

1

筛选

214

1098

2016年

12月

4

阻容元件检测岗

2

复验

870

1261

2016年

11月

4

阻容元件检测岗

2

复验

391

1261

2016年

11月

8

机电元件检测岗

2

复验

874

1362

2016年

12月

8

机电元件检测岗

2

复验

488

1362

2016年

11月

8

机电元件检测岗

1

筛选

640

1457

2016年

12月

8

机电元件检测岗

1

筛选

817

1457

2016年

12月

5

分立器件检测岗

1

筛选

849

1723

2016年

11月

5

分立器件检测岗

1

筛选

874

1723

那么我们猜想,如果按照年份,以及试验类型分区求和的话,那么出来的累计产值是不是只有两个值,一个是2016年复验试验的产值,一个是2016年筛选试验的产值,测试SQL如下:

select
year_name,--年份名称
month_name,--月份名称
post_code,--岗位编码
post_name,--岗位名称
testtype_code,--试验类型编码
testtype_name,--试验类型名称
cost_amt,--产值
sum(cost_amt) over (partition by year_name,testtype_code,testtype_name) as leiji_amt--累计产值
from test_2021
where year_name = '2016年'
order by year_name,month_name

该SQL执行结果如下(按累计产值排序):

年份名称

月份名称

岗位编码

岗位名称

试验类型编码

试验类型名称

产值

累计产值

2016年

12月

4

阻容元件检测岗

2

复验

870

4782

2016年

11月

5

分立器件检测岗

2

复验

795

4782

2016年

11月

4

阻容元件检测岗

2

复验

391

4782

2016年

12月

8

机电元件检测岗

2

复验

488

4782

2016年

12月

7

电连接器器件检测岗

2

复验

407

4782

2016年

12月

5

分立器件检测岗

2

复验

76

4782

2016年

12月

6

微波器件检测岗

2

复验

22

4782

2016年

11月

6

微波器件检测岗

2

复验

802

4782

2016年

11月

7

电连接器器件检测岗

2

复验

57

4782

2016年

11月

8

机电元件检测岗

2

复验

874

4782

2016年

12月

5

分立器件检测岗

1

筛选

849

5299

2016年

12月

8

机电元件检测岗

1

筛选

817

5299

2016年

12月

6

微波器件检测岗

1

筛选

633

5299

2016年

12月

4

阻容元件检测岗

1

筛选

214

5299

2016年

11月

5

分立器件检测岗

1

筛选

874

5299

2016年

11月

8

机电元件检测岗

1

筛选

640

5299

2016年

11月

4

阻容元件检测岗

1

筛选

884

5299

2016年

11月

6

微波器件检测岗

1

筛选

388

5299

3.2、测试over (order by xxx,yyy)按照xxx,yyy字段排序进行累计

需求:按照年月进行累计,即2016年11月的累计产值为11的和(2016年只有11月以后的数据),12月为11月和12月的和,SQL如下

select
year_name,--年份名称
month_name,--月份名称
post_code,--岗位编码
post_name,--岗位名称
testtype_code,--试验类型编码
testtype_name,--试验类型名称
cost_amt,--产值
sum(cost_amt) over (order by year_name,month_name) as leiji_amt--累计产值
from test_2021
where year_name = '2016年'
order by year_name,month_name

执行结果如下:

年份名称

月份名称

岗位编码

岗位名称

试验类型编码

试验类型名称

产值

累计产值

2016年

11月

4

阻容元件检测岗

1

筛选

884

5705

2016年

11月

8

机电元件检测岗

2

复验

874

5705

2016年

11月

5

分立器件检测岗

2

复验

795

5705

2016年

11月

6

微波器件检测岗

1

筛选

388

5705

2016年

11月

4

阻容元件检测岗

2

复验

391

5705

2016年

11月

7

电连接器器件检测岗

2

复验

57

5705

2016年

11月

5

分立器件检测岗

1

筛选

874

5705

2016年

11月

8

机电元件检测岗

1

筛选

640

5705

2016年

11月

6

微波器件检测岗

2

复验

802

5705

2016年

12月

6

微波器件检测岗

2

复验

22

10081

2016年

12月

8

机电元件检测岗

2

复验

488

10081

2016年

12月

7

电连接器器件检测岗

2

复验

407

10081

2016年

12月

5

分立器件检测岗

1

筛选

849

10081

2016年

12月

4

阻容元件检测岗

1

筛选

214

10081

2016年

12月

5

分立器件检测岗

2

复验

76

10081

2016年

12月

4

阻容元件检测岗

2

复验

870

10081

2016年

12月

8

机电元件检测岗

1

筛选

817

10081

2016年

12月

6

微波器件检测岗

1

筛选

633

10081

作为对比,同样的SQL,我们将 order by 改为 partition by ,看一下结果,SQL以及执行结果如下:

select
year_name,--年份名称
month_name,--月份名称
post_code,--岗位编码
post_name,--岗位名称
testtype_code,--试验类型编码
testtype_name,--试验类型名称
cost_amt,--产值
sum(cost_amt) over (partition by year_name,month_name) as leiji_amt--累计产值
from test_2021
where year_name = '2016年'
order by year_name,month_name

年份名称

月份名称

岗位编码

岗位名称

试验类型编码

试验类型名称

产值

累计产值

2016年

11月

4

阻容元件检测岗

1

筛选

884

5705

2016年

11月

8

机电元件检测岗

2

复验

874

5705

2016年

11月

5

分立器件检测岗

2

复验

795

5705

2016年

11月

6

微波器件检测岗

1

筛选

388

5705

2016年

11月

4

阻容元件检测岗

2

复验

391

5705

2016年

11月

7

电连接器器件检测岗

2

复验

57

5705

2016年

11月

5

分立器件检测岗

1

筛选

874

5705

2016年

11月

8

机电元件检测岗

1

筛选

640

5705

2016年

11月

6

微波器件检测岗

2

复验

802

5705

2016年

12月

6

微波器件检测岗

2

复验

22

4376

2016年

12月

8

机电元件检测岗

2

复验

488

4376

2016年

12月

7

电连接器器件检测岗

2

复验

407

4376

2016年

12月

5

分立器件检测岗

1

筛选

849

4376

2016年

12月

4

阻容元件检测岗

1

筛选

214

4376

2016年

12月

5

分立器件检测岗

2

复验

76

4376

2016年

12月

4

阻容元件检测岗

2

复验

870

4376

2016年

12月

8

机电元件检测岗

1

筛选

817

4376

2016年

12月

6

微波器件检测岗

1

筛选

633

4376

以上11月产值5705加上12月的产值4376等于10081,刚好为 order by 中的12月累计值10081。

3.3、over (partition by xxx order by yyy)按照 xxx 字段分区,并按照yyy字段排序进行累计

需求:求出同一年份,同一岗位,同一试验类型每个月的产值累计值。这里既要按年份、岗位、试验类型分区,又要求月份的累计值,所以就要用over (partition by xxx order by yyy),SQL如下:

select
year_name,--年份名称
month_name,--月份名称
post_code,--岗位编码
post_name,--岗位名称
testtype_code,--试验类型编码
testtype_name,--试验类型名称
cost_amt,--产值
sum(cost_amt) over (partition by year_name,post_code,post_name,testtype_code,testtype_name order by month_name) as leiji_amt
from test_2021
where year_name = '2016年'
order by year_name,month_name

执行结果如下:

序号

年份名称

月份名称

岗位编码

岗位名称

试验类型编码

试验类型名称

产值

累计产值

1

2016年

11月

4

阻容元件检测岗

1

筛选

884

884

2

2016年

11月

6

微波器件检测岗

1

筛选

388

388

3

2016年

11月

8

机电元件检测岗

2

复验

874

874

4

2016年

11月

8

机电元件检测岗

1

筛选

640

640

5

2016年

11月

7

电连接器器件检测岗

2

复验

57

57

6

2016年

11月

6

微波器件检测岗

2

复验

802

802

7

2016年

11月

5

分立器件检测岗

2

复验

795

795

8

2016年

11月

5

分立器件检测岗

1

筛选

874

874

9

2016年

11月

4

阻容元件检测岗

2

复验

391

391

10

2016年

12月

6

微波器件检测岗

1

筛选

633

1021

11

2016年

12月

8

机电元件检测岗

2

复验

488

1362

12

2016年

12月

5

分立器件检测岗

2

复验

76

871

13

2016年

12月

8

机电元件检测岗

1

筛选

817

1457

14

2016年

12月

4

阻容元件检测岗

1

筛选

214

1098

15

2016年

12月

6

微波器件检测岗

2

复验

22

824

16

2016年

12月

4

阻容元件检测岗

2

复验

870

1261

17

2016年

12月

7

电连接器器件检测岗

2

复验

407

464

18

2016年

12月

5

分立器件检测岗

1

筛选

849

1723

数据核对:以2016年阻容元件检测岗的筛选试验为例,在11月的产值为884(第1行数据),累计产值为884,在12月的产值为214(第14行数据),12月的累计产值为1098,即为11月的884与12月的214的和。