SQL中的聚合函数,顾名思义是聚集合并的意思,是对某个范围内的数值进行聚合,聚合后的结果是一个值或是各个类别对应的值。直接聚合得到的结果是所有数据合并,分组聚合(group by)得到的结果是分组合并。

这种聚合函数得到的数据行数是小于基础数据行数的,但是我们经常会有这样的需求,就是既希望看基础数据同时也希望查看聚合后的数据,这个时候聚合函数就满足不了我们了,窗口函数就派上用场了。窗口函数就是既可以显示原始基础数据也可以显示聚合数据。

1.测试数据

学习当然不能凭空想象,需要大量的实践来提高学习效果。

先编排测试数据。

-- 创建测试表
create table temp_cwh_window
(
shopname varchar(10),
sales number,
date2 date
);
-- 插入数据
insert into temp_cwh_window values('淘宝','50',to_date('20191013','yyyymmdd'));
insert into temp_cwh_window values('淘宝','35',to_date('20191014','yyyymmdd'));
insert into temp_cwh_window values('淘宝','63',to_date('20191015','yyyymmdd'));
insert into temp_cwh_window values('天猫','15',to_date('20191013','yyyymmdd'));
insert into temp_cwh_window values('天猫','59',to_date('20191014','yyyymmdd'));
insert into temp_cwh_window values('天猫','63',to_date('20191015','yyyymmdd'));
insert into temp_cwh_window values('京东','159',to_date('20191013','yyyymmdd'));
insert into temp_cwh_window values('京东','32',to_date('20191014','yyyymmdd'));
insert into temp_cwh_window values('京东','59',to_date('20191015','yyyymmdd'));
-- 查询
select * from temp_cwh_window;
序号 shopname sales date2
1 淘宝 50 2019/10/13
2 淘宝 35 2019/10/14
3 淘宝 63 2019/10/15
4 天猫 15 2019/10/13
5 天猫 59 2019/10/14
6 天猫 63 2019/10/15
7 京东 159 2019/10/13
8 京东 32 2019/10/14
9 京东 59 2019/10/15

2.聚合函数+over()

over()的作用就是告诉SQL引擎:按区域对数据进行分区,然后累计每个切片的总额,再全部展示。

over函数指明在那些字段上做分析,其内跟Partition by表示对数据进行分组。注意Partition by可以有多个字段。

over函数可以和其它聚集函数、分析函数搭配,起到不同的作用。例如sum,还有诸如rankdense_rank, min, max等。

  • 平均销量
select shopname,
sales,
date2,
avg(sales) over()
from temp_cwh_window;

3.partition by子句

使用partition by子句可以进行分组操作,类似于group by,需要与over()搭配使用。

select shopname,
sales,
date2,
avg(sales) over(partition by shopname)
from temp_cwh_window;

4.order by子句

使用order by子句可以按照某一列数值进行排序,可与序列函数ntilerow_numberlagleadfirst_valuelast_value等结合使用。

当 order by 与聚合函数一起使用时,是顺序聚合的。类似于累计和的效果,截止当前行的累计,这里需要特别注意。

select shopname,
sales,
date2,
sum(sales) over(partition by shopname order by date2)
from temp_cwh_window;
-- 运行结果
1 京东 159 2019/10/13 159
2 京东 32 2019/10/14 191
3 京东 59 2019/10/15 250
4 淘宝 50 2019/10/13 50
5 淘宝 35 2019/10/14 85
6 淘宝 63 2019/10/15 148
7 天猫 15 2019/10/13 15
8 天猫 59 2019/10/14 74
9 天猫 63 2019/10/15 137

当order by与序列函数一起使用时用于排序。

5.序列函数

序列函数,就是可以将数据整理成一个有序的序列,然后可以在这个序列里面挑选我们想要的序列对应的数据。

5.1 分析函数之 ntile

ntile函数对一个数据分区中的有序结果集进行划分,将其分组为各个桶,并为每个小组分配一个唯一的组编号。默认是对表在不做任何操作之前进行切片分组的。

注:必须要加order by

  • 随机切分为3组
select shopname,
sales,
date2,
ntile(3) over(order by null)
from temp_cwh_window;
  • 先分组排序再切分
select shopname,
sales,
date2,
ntile(3) over(partition by shopname order by sales)
from temp_cwh_window;
  • 空值排最后
select shopname,
sales,
date2,
ntile(3) over(partition by shopname order by sales desc nulls last)
from temp_cwh_window;

5.2 分析函数之 row_number

row_number() 从 1 开始,按照顺序(注意这里是顺序不是排序)生成该条数据在分组内的对应的序列数,row_number() 的值不会存在重复,当排序的值相同时,按照表中记录的顺序进行排列。

row_number() 一般需要与 order by 进行结合使用。

rank是不连续排名函数(1,1,3,3,5),dense_rank 是连续排名函数(1,1,2,2,3)。

select shopname,
sales,
date2,
row_number() over(partition by shopname order by date2) as rank
from temp_cwh_window;

然后只需要将 rank = 1 部分数据取出即可。

5.3 分析函数之 lag、lead

lag 的英文意思是滞后,而 lead 的英文意思是超前。

对应的 lag 是让数据向后移动,而 lead 是让数据向前移动。

select shopname,
sales,
date2,
lag(date2,1) over(partition by shopname order by date2)
from temp_cwh_window;
-- 结果
1 京东 159 2019/10/13
2 京东 32 2019/10/14 2019/10/13
3 京东 59 2019/10/15 2019/10/14
4 淘宝 50 2019/10/13
5 淘宝 35 2019/10/14 2019/10/13
6 淘宝 63 2019/10/15 2019/10/14
7 天猫 15 2019/10/13
8 天猫 59 2019/10/14 2019/10/13
9 天猫 63 2019/10/15 2019/10/14
select shopname,
sales,
date2,
lead(date2,1) over(partition by shopname order by date2)
from temp_cwh_window;
-- 结果
1 京东 159 2019/10/13 2019/10/14
2 京东 32 2019/10/14 2019/10/15
3 京东 59 2019/10/15
4 淘宝 50 2019/10/13 2019/10/14
5 淘宝 35 2019/10/14 2019/10/15
6 淘宝 63 2019/10/15
7 天猫 15 2019/10/13 2019/10/14
8 天猫 59 2019/10/14 2019/10/15
9 天猫 63 2019/10/15

5.4 分析函数之 first_value、last_value

first_valuelast_value 都是顾名思义,就是获取第一个值和最后一个值。

但是不是真正意义上的第一个或最后一个,而是截至到当前行的第一个或最后一个。

select shopname,
sales,
date2,
first_value(date2) over(partition by shopname order by date2),
last_value(date2) over(partition by shopname order by date2)
from temp_cwh_window;
-- 结果
1 京东 159 2019/10/13 2019/10/13 2019/10/13
2 京东 32 2019/10/14 2019/10/13 2019/10/14
3 京东 59 2019/10/15 2019/10/13 2019/10/15
4 淘宝 50 2019/10/13 2019/10/13 2019/10/13
5 淘宝 35 2019/10/14 2019/10/13 2019/10/14
6 淘宝 63 2019/10/15 2019/10/13 2019/10/15
7 天猫 15 2019/10/13 2019/10/13 2019/10/13
8 天猫 59 2019/10/14 2019/10/13 2019/10/14
9 天猫 63 2019/10/15 2019/10/13 2019/10/15

Oracle学习笔记:窗口函数的更多相关文章

  1. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  2. oracle学习笔记第一天

    oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字   1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...

  3. Oracle学习笔记——点滴汇总

    Oracle学习笔记——点滴汇总 http://www.botangdb.com/ Oracle GI = Grid Infrastructure = ASM + Cluster

  4. Oracle学习笔记之四sp1,Oracle 11g的常用函数

    从Oracle学习笔记之四,SQL语言入门中摘出来的,独立成一章节 3.1 字符类函数 ASCII(c)和CHR(i)    分别用于返回一个字符的ASCII码和返回给定ASCII值所对应的字符. C ...

  5. Oracle学习笔记之四,SQL语言入门

    1. SQL语言概述 1.1 SQL语言特点 集合性,SQL可以的高层的数据结构上进行工作,工作时不是单条地处理记录,而对数据进行成组的处理. 统一性,操作任务主要包括:查询数据:插入.修改和删除数据 ...

  6. Oracle学习笔记—数据字典和常用命令(转载)

    转载自: oracle常用数据字典和SQL语句总结 Oracle常用命令大全(很有用,做笔记) 一.Oracle数据字典 数据字典是Oracle存放有关数据库信息的地方,其用途是用来描述数据的.比如一 ...

  7. oracle学习笔记(一)用户管理

    --oracle学习第一天 --连接 @后面连接数据库实例,具体连接到那个数据库 conn scott/tiger@MYORA1; --修改密码 passw; --显示用户 show user; -- ...

  8. 吴裕雄--天生自然 oracle学习笔记:oracle理论学习详解及各种简单操作例子

    1. 数据库的发展过程 层次模型 -->网状模型 -->关系模型 -->对象关系模型 2. 关于数据库的概念 DB:数据库(存储信息的仓库) DBMS:数据库管理系统(用于管理数据库 ...

  9. Oracle 学习笔记 11 -- 视图 (VIEW)

    本次必须学习一个全新的概念-- 视图 (VIEW).在前面的笔记中曾提到过,数据对象包含:表.视图.序列.索引和同义词.前面的笔记都是对表的想剖析,那么本次笔记就对视图的世界进行深入的剖析. 视图是通 ...

随机推荐

  1. 自定义vue-cli生成项目模板配置(1)

    最近在读<变量>,目前得到的认知之一:慢变量才是决定事物长期发展的因素. 打算自定义vue-cli的脚手架或者根据自己的需要设置项目模板的相关参数,很大程度与慢变量这个概念相关. 当然,我 ...

  2. easyU之tabs选项卡

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  3. coursera 视频总是缓冲或者无法观看的解决办法(Windows 和 Linux 系统 环境)

    现在读了一个机器学习方向的博士,虽然这么长时间也没有学明白什么,但是没事的时候也会看看一些书籍和资料,学这个方向的人基本都会看过吴恩达的coursera课程上的机器学习课程,我也是如此,不过交了钱以后 ...

  4. python设计模式-命令模式

    命令模式就是对命令的封装.所谓封装命令,就是将一系列操作封装到命令类中,并且命令类只需要对外公开一个执行方法execute,调用此命令的对象只需要执行命令的execute方法就可以完成所有的操作.这样 ...

  5. WPF学习笔记 - 如何用WPF创建单实例应用程序

    使用一个已命名的(操作系统范围的)互斥量. bool mutexIsNew; using(System.Threading.Mutex m = new System.Threading.Mulex(t ...

  6. openstack核心组件--neutron网络服务(4)

    一.neutron 介绍:   Neutron 概述 传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备:而云环境下的网络已经变得非常复杂,特别是在多租户场景里,用户随时都可能需要 ...

  7. ScrollView-基本设置

    一: 掌握两点: 1. ScrollView必须有一个确定的高度才能正常工作,因为它实际上所做的就是将一系列不确定高度的子组件装进一个确定高度的容器(通过滚动操作).要给一个ScrollView确定一 ...

  8. 文件夹的层级选择< OC实现 >

    类似文件夹的层级选择,可以搜索和创建新文件夹,点击路径标题可以返回对应层级. 界面有点丑,功能还是大概实现了的!! 代码有点多,还是附上地址吧,有兴趣的可以看看哟!!!    https://gith ...

  9. C# 3Des加密解密

      第三方的加密规则约定:加密经过3DES加密后的Base64 编码 最近在对接一个第三方接口,请求参数和响应参数全采用3des加密规则,由于我是用.NET对接的,而第三方是Java开发的,所以两种程 ...

  10. Django 虚拟化环境创建

    A:linux下的方法: 1.用python3.6内置的venv创建名为 typeidea-env虚拟化环境: python3.6 -m venv typeidea-env 2.激活环境: cd ty ...