over (partition by xxx order by yyy)开窗函数介绍
迪丽瓦拉
2024-03-07 18:15:33
0

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_NAMEVARCHAR2(19)Y年份名称
MONTH_NAMEVARCHAR2(11)Y月份名称
POST_CODEVARCHAR2(52)Y岗位编码
POST_NAMEVARCHAR2(300)Y岗位名称
TESTTYPE_CODECHAR(2)Y试验类型编码
TESTTYPE_NAMECHAR(6)Y试验类型名称
COST_AMTNUMBERY产值

测试表 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复验3911261
2016年11月6微波器件检测岗2复验802824
2016年11月4阻容元件检测岗1筛选8841098
2016年11月7电连接器器件检测岗2复验57464
2016年11月5分立器件检测岗2复验795871
2016年11月8机电元件检测岗2复验8741362
2016年11月6微波器件检测岗1筛选3881021
2016年11月8机电元件检测岗1筛选6401457
2016年11月5分立器件检测岗1筛选8741723
2016年12月4阻容元件检测岗1筛选2141098
2016年12月7电连接器器件检测岗2复验407464
2016年12月8机电元件检测岗2复验4881362
2016年12月8机电元件检测岗1筛选8171457
2016年12月6微波器件检测岗2复验22824
2016年12月6微波器件检测岗1筛选6331021
2016年12月5分立器件检测岗2复验76871
2016年12月4阻容元件检测岗2复验8701261
2016年12月5分立器件检测岗1筛选8491723

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

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

年份名称月份名称岗位编码岗位名称试验类型编码试验类型名称产值累计产值
2016年11月7电连接器器件检测岗2复验57464
2016年12月7电连接器器件检测岗2复验407464
2016年12月6微波器件检测岗2复验22824
2016年11月6微波器件检测岗2复验802824
2016年12月5分立器件检测岗2复验76871
2016年11月5分立器件检测岗2复验795871
2016年12月6微波器件检测岗1筛选6331021
2016年11月6微波器件检测岗1筛选3881021
2016年11月4阻容元件检测岗1筛选8841098
2016年12月4阻容元件检测岗1筛选2141098
2016年12月4阻容元件检测岗2复验8701261
2016年11月4阻容元件检测岗2复验3911261
2016年11月8机电元件检测岗2复验8741362
2016年12月8机电元件检测岗2复验4881362
2016年11月8机电元件检测岗1筛选6401457
2016年12月8机电元件检测岗1筛选8171457
2016年12月5分立器件检测岗1筛选8491723
2016年11月5分立器件检测岗1筛选8741723

那么我们猜想,如果按照年份,以及试验类型分区求和的话,那么出来的累计产值是不是只有两个值,一个是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复验8704782
2016年11月5分立器件检测岗2复验7954782
2016年11月4阻容元件检测岗2复验3914782
2016年12月8机电元件检测岗2复验4884782
2016年12月7电连接器器件检测岗2复验4074782
2016年12月5分立器件检测岗2复验764782
2016年12月6微波器件检测岗2复验224782
2016年11月6微波器件检测岗2复验8024782
2016年11月7电连接器器件检测岗2复验574782
2016年11月8机电元件检测岗2复验8744782
2016年12月5分立器件检测岗1筛选8495299
2016年12月8机电元件检测岗1筛选8175299
2016年12月6微波器件检测岗1筛选6335299
2016年12月4阻容元件检测岗1筛选2145299
2016年11月5分立器件检测岗1筛选8745299
2016年11月8机电元件检测岗1筛选6405299
2016年11月4阻容元件检测岗1筛选8845299
2016年11月6微波器件检测岗1筛选3885299
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筛选8845705
2016年11月8机电元件检测岗2复验8745705
2016年11月5分立器件检测岗2复验7955705
2016年11月6微波器件检测岗1筛选3885705
2016年11月4阻容元件检测岗2复验3915705
2016年11月7电连接器器件检测岗2复验575705
2016年11月5分立器件检测岗1筛选8745705
2016年11月8机电元件检测岗1筛选6405705
2016年11月6微波器件检测岗2复验8025705
2016年12月6微波器件检测岗2复验2210081
2016年12月8机电元件检测岗2复验48810081
2016年12月7电连接器器件检测岗2复验40710081
2016年12月5分立器件检测岗1筛选84910081
2016年12月4阻容元件检测岗1筛选21410081
2016年12月5分立器件检测岗2复验7610081
2016年12月4阻容元件检测岗2复验87010081
2016年12月8机电元件检测岗1筛选81710081
2016年12月6微波器件检测岗1筛选63310081

作为对比,同样的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筛选8845705
2016年11月8机电元件检测岗2复验8745705
2016年11月5分立器件检测岗2复验7955705
2016年11月6微波器件检测岗1筛选3885705
2016年11月4阻容元件检测岗2复验3915705
2016年11月7电连接器器件检测岗2复验575705
2016年11月5分立器件检测岗1筛选8745705
2016年11月8机电元件检测岗1筛选6405705
2016年11月6微波器件检测岗2复验8025705
2016年12月6微波器件检测岗2复验224376
2016年12月8机电元件检测岗2复验4884376
2016年12月7电连接器器件检测岗2复验4074376
2016年12月5分立器件检测岗1筛选8494376
2016年12月4阻容元件检测岗1筛选2144376
2016年12月5分立器件检测岗2复验764376
2016年12月4阻容元件检测岗2复验8704376
2016年12月8机电元件检测岗1筛选8174376
2016年12月6微波器件检测岗1筛选6334376

以上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

执行结果如下:

序号年份名称月份名称岗位编码岗位名称试验类型编码试验类型名称产值累计产值
12016年11月4阻容元件检测岗1筛选884884
22016年11月6微波器件检测岗1筛选388388
32016年11月8机电元件检测岗2复验874874
42016年11月8机电元件检测岗1筛选640640
52016年11月7电连接器器件检测岗2复验5757
62016年11月6微波器件检测岗2复验802802
72016年11月5分立器件检测岗2复验795795
82016年11月5分立器件检测岗1筛选874874
92016年11月4阻容元件检测岗2复验391391
102016年12月6微波器件检测岗1筛选6331021
112016年12月8机电元件检测岗2复验4881362
122016年12月5分立器件检测岗2复验76871
132016年12月8机电元件检测岗1筛选8171457
142016年12月4阻容元件检测岗1筛选2141098
152016年12月6微波器件检测岗2复验22824
162016年12月4阻容元件检测岗2复验8701261
172016年12月7电连接器器件检测岗2复验407464
182016年12月5分立器件检测岗1筛选8491723

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

相关内容