pg 窗口函数
窗口函数基于结果集进行计算,将计算出的结果合并到输出的结果集上,并返回多行。使用窗口函数能大幅度简化SQL代码。
gaussdb提供内置的窗口函数,例如row_num()、rank()、lag()等,除了内置的窗口函数外,聚合函数、自定义函数后接OVER属性也可以作为窗口函数。
1,创建测试表并插入数据。
postgres=# DROP TABLE IF EXISTS scores;
NOTICE: table "scores" does not exist, skipping
DROP TABLE
postgres=# CREATE TABLE scores(id serial PRIMARY KEY,subject varchar(32),stu_name varchar(32),score numeric(3,0));
CREATE TABLE
postgres=# INSERT INTO scores(subject,stu_name,score) VALUES('Chinese','user1',80),('Chinese','user2',90),('Chinese','user3',90),('math','user1',90),('math','user2',80),('math','user3',100),('English','user1',80),('English','user2',90),('English','user3',70);
INSERT 0 9
postgres=# SELECT * FROM scores;
id | subject | stu_name | score
----+---------+----------+-------
1 | Chinese | user1 | 80
2 | Chinese | user2 | 90
3 | Chinese | user3 | 90
4 | math | user1 | 90
5 | math | user2 | 80
6 | math | user3 | 100
7 | English | user1 | 80
8 | English | user2 | 90
9 | English | user3 | 70
(9 rows)
2,avg() OVER()计算分组后数据的平均值。
postgres=# SELECT subject,stu_name,score,avg(score) OVER(PARTITION BY subject) FROM scores;
subject | stu_name | score | avg
---------+----------+-------+---------------------
Chinese | user1 | 80 | 86.6666666666666667
Chinese | user2 | 90 | 86.6666666666666667
Chinese | user3 | 90 | 86.6666666666666667
English | user3 | 70 | 80.0000000000000000
English | user1 | 80 | 80.0000000000000000
English | user2 | 90 | 80.0000000000000000
math | user1 | 90 | 90.0000000000000000
math | user2 | 80 | 90.0000000000000000
math | user3 | 100 | 90.0000000000000000
(9 rows)
3,row_number() OVER()对分组后的数据标注行号,从1开始。
postgres=# SELECT row_number() OVER(PARTITION BY subject ORDER BY score DESC),* FROM scores;
row_number | id | subject | stu_name | score
------------+----+---------+----------+-------
1 | 2 | Chinese | user2 | 90
2 | 3 | Chinese | user3 | 90
3 | 1 | Chinese | user1 | 80
1 | 8 | English | user2 | 90
2 | 7 | English | user1 | 80
3 | 9 | English | user3 | 70
1 | 6 | math | user3 | 100
2 | 4 | math | user1 | 90
3 | 5 | math | user2 | 80
(9 rows)
4,rank() OVER()与row_number() OVER()类似主要区别是当组内某行字段值相同时,行号重复并且行号产生间隙。
postgres=# SELECT rank() OVER(PARTITION BY subject ORDER BY score DESC),* FROM scores;
rank | id | subject | stu_name | score
------+----+---------+----------+-------
1 | 2 | Chinese | user2 | 90
1 | 3 | Chinese | user3 | 90
3 | 1 | Chinese | user1 | 80
1 | 8 | English | user2 | 90
2 | 7 | English | user1 | 80
3 | 9 | English | user3 | 70
1 | 6 | math | user3 | 100
2 | 4 | math | user1 | 90
3 | 5 | math | user2 | 80
(9 rows)
5,dense_rank() OVER()与rank() 类似,主要区别为当组内某行字段值相同时,虽然重复行号,但行号不产生间隙。
postgres=# SELECT dense_rank() OVER(PARTITION BY subject ORDER BY score DESC),* FROM scores;
dense_rank | id | subject | stu_name | score
------------+----+---------+----------+-------
1 | 2 | Chinese | user2 | 90
1 | 3 | Chinese | user3 | 90
2 | 1 | Chinese | user1 | 80
1 | 8 | English | user2 | 90
2 | 7 | English | user1 | 80
3 | 9 | English | user3 | 70
1 | 6 | math | user3 | 100
2 | 4 | math | user1 | 90
3 | 5 | math | user2 | 80
(9 rows)
6,lag() OVER()可以获取行偏移offset那行字段的数据。
postgres=# SELECT LAG(id,-1) OVER(),* FROM scores;
lag | id | subject | stu_name | score
-----+----+---------+----------+-------
2 | 1 | Chinese | user1 | 80
3 | 2 | Chinese | user2 | 90
4 | 3 | Chinese | user3 | 90
5 | 4 | math | user1 | 90
6 | 5 | math | user2 | 80
7 | 6 | math | user3 | 100
8 | 7 | English | user1 | 80
9 | 8 | English | user2 | 90
| 9 | English | user3 | 70
(9 rows) postgres=# SELECT LAG(id,1,100) OVER(),* FROM scores;--不存在时指定默认值
lag | id | subject | stu_name | score
-----+----+---------+----------+-------
100 | 1 | Chinese | user1 | 80
1 | 2 | Chinese | user2 | 90
2 | 3 | Chinese | user3 | 90
3 | 4 | math | user1 | 90
4 | 5 | math | user2 | 80
5 | 6 | math | user3 | 100
6 | 7 | English | user1 | 80
7 | 8 | English | user2 | 90
8 | 9 | English | user3 | 70
(9 rows)
7,first_value() OVER()用来取结果集每一个分组的第一行数据的字段值。
postgres=# SELECT first_value(score) OVER(PARTITION BY subject ORDER BY score DESC),* FROM scores;
first_value | id | subject | stu_name | score
-------------+----+---------+----------+-------
90 | 2 | Chinese | user2 | 90
90 | 3 | Chinese | user3 | 90
90 | 1 | Chinese | user1 | 80
90 | 8 | English | user2 | 90
90 | 7 | English | user1 | 80
90 | 9 | English | user3 | 70
100 | 6 | math | user3 | 100
100 | 4 | math | user1 | 90
100 | 5 | math | user2 | 80
(9 rows)
8,last_value() OVER()用来取结果集每一个分组的最后一行数据的字段值。
postgres=# SELECT last_value(score) OVER(PARTITION BY subject),* FROM scores;
last_value | id | subject | stu_name | score
------------+----+---------+----------+-------
90 | 1 | Chinese | user1 | 80
90 | 2 | Chinese | user2 | 90
90 | 3 | Chinese | user3 | 90
90 | 9 | English | user3 | 70
90 | 7 | English | user1 | 80
90 | 8 | English | user2 | 90
100 | 4 | math | user1 | 90
100 | 5 | math | user2 | 80
100 | 6 | math | user3 | 100
(9 rows)
9,nth_value() OVER()用来取结果集每一个分组的指定行数据的字段值。
postgres=# SELECT nth_value(score,2) OVER(PARTITION BY subject),* FROM scores;
nth_value | id | subject | stu_name | score
-----------+----+---------+----------+-------
90 | 1 | Chinese | user1 | 80
90 | 2 | Chinese | user2 | 90
90 | 3 | Chinese | user3 | 90
80 | 9 | English | user3 | 70
80 | 7 | English | user1 | 80
80 | 8 | English | user2 | 90
80 | 4 | math | user1 | 90
80 | 5 | math | user2 | 80
80 | 6 | math | user3 | 100
(9 rows)
10,如果窗口函数需要多次使用,可以使用窗口函数别名。
postgres=# SELECT avg(score) OVER(r),sum(score) OVER(r),* FROM scores WINDOW r AS (PARTITION BY subject);
avg | sum | id | subject | stu_name | score
---------------------+-----+----+---------+----------+-------
86.6666666666666667 | 260 | 1 | Chinese | user1 | 80
86.6666666666666667 | 260 | 2 | Chinese | user2 | 90
86.6666666666666667 | 260 | 3 | Chinese | user3 | 90
80.0000000000000000 | 240 | 9 | English | user3 | 70
80.0000000000000000 | 240 | 7 | English | user1 | 80
80.0000000000000000 | 240 | 8 | English | user2 | 90
90.0000000000000000 | 270 | 4 | math | user1 | 90
90.0000000000000000 | 270 | 5 | math | user2 | 80
90.0000000000000000 | 270 | 6 | math | user3 | 100
(9 rows)
pg 窗口函数的更多相关文章
- 专访探探DBA张文升:PG在互联网应用中同样也跑的很欢畅
张文升认为,PG无论在可靠性和性能方面都不输其它任何关系型数据库 张文升,探探DBA,负责探探的数据库架构.运维和调优的工作.拥有8年开发经验,曾任去哪儿网DBA. 9月24日,张文升将参加在 ...
- 数据库周刊31丨openGauss 正式开源;7月数据库排行榜发布;浙江移动国产数据库AntDB迁移;oracle ADG跨版本搭建;PG解决社保问题;mysqlbinlog解析……
摘要:墨天轮数据库周刊第31期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.openGauss 正式开源,华为公开发布源代码[摘要]6月1日,华为正式宣布开源数据库能 ...
- 简析服务端通过GT导入SHP至PG的方法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 项目中需要在浏览器端直接上传SHP后服务端进行数据的自动入PG ...
- PG 中 JSON 字段的应用
13 年发现 pg 有了 json 类型,便从 oracle 转 pg,几年下来也算比较熟稔了,总结几个有益的实践. 用途一:存储设计时无法预料的文档性的数据.比如,通常可以在人员表准备一个 json ...
- pg gem 安装(postgresql94)
使用下面命令安装报错 gem install pg 错误: [root@AS-test middle_database]# gem install pgBuilding native extensio ...
- #pg学习#postgresql的安装
1.按照官网给的步骤编译安装(Mac安装是比较容易的,相比Liunx) cd /Users/renlipeng/Desktop/postgresql-9.5.1 ./configure --prefi ...
- Over:窗口函数(滑动聚合)
Over 窗口函数在Select 子句中,对查询的结果集进行“滑动-聚合”运算:如果使用count,那么基于滑动窗口的聚合语义同 base+1 累加:如果使用sum,那么基于滑动窗口的聚合语义等同于数 ...
- SQL Server中的窗口函数
简介 SQL Server 2012之后对窗口函数进行了极大的加强,但对于很多开发人员来说,对窗口函数却不甚了解,导致了这样强大的功能被浪费,因此本篇文章主要谈一谈SQL Server中窗口函 ...
- PG 函数的易变性(Function Volatility Categories)
此概念的接触是在做分区表的时候碰到的,分区表按时间字段分区,在查询时当where条件中时间为now()或者current_time()等时是无法查询的,即使进行格式转换也不行,只有是时间格式如‘201 ...
- mysql 序列与pg序列的比较
mysql序列(这里只谈innodb引擎): 在使用mysql的AUTO_INCREMENT时,使用AUTO_INCREMENT的字段必须建有索引,也可以为索引的一部分.当没有索引时会报错: ...
随机推荐
- usbip 非源码安装
对于很多 Linux 发行版不能直接搜索 usbip 的包名进行安装 Kylin OS 其实他是包含在一个名为 linux-tools-generic 的软件包中的 对于 UOS 操作系统可以直接安装 ...
- GPT和MBR分区格式
目前市面上磁盘有两个格式,一种是GPT(Master Boot Record)分区一种是MBR(Master Boot Record)分区. 像UEFI用于取代老旧的BIOS,而GPT则为的是取代老旧 ...
- for循环axios套axios调用,同步调取
1.function getsdd(){}事件 async/await把异步进行设置成同步进行 var url = '/api/runtime/form/save'; function checkAd ...
- mysql 创建函数失败解决办法,版本 8.0.26
报错信息:[Err] 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declarat ...
- redhat安装opencv2.4.13
1.官网下载OpenCV2.4.5 http://opencv.org/ 解压到home/用户名/opencv2.4.5 2.安装cmake $sudo apt-get install cmake ...
- go语言学习教程
go语言学习教程 集合了连接go routine.go连接redis.go连接kafka等示例 https://github.com/fastbpmn/go-study TRANSLATE with ...
- 使用nodejs中遇到的问题
1.post请求必须使用express的一个中间件body-parser一下不然req.body会一直为空 2.node.js这种东西后端跨域就行,前端就别跨域了,不然会一直报错 3.sql语句那个s ...
- linux中用命令导出、导入mysql数据库表
一.导出数据 1.使用场景:在没有数据库可视化工具的情况下备份导出数据库. 命令如下: mysqldump -u用户名 -p 数据库名 > 数据库名.sql mysqldump -u root ...
- chia P图安装
https://techtellectual.com/chia-plotting-guide-installing-plotman-and-mad-max-in-linux/ Chia 绘图指南:在 ...
- 关于DVWA踩坑
部署好DVWA开始欢天喜地用起来,结果有个问题,不管怎么设置这个安全等级,都显示为Impossible 原因也很显然 其实我并不太理解为什么这里要放在cookie里面,而且还放了两条. 处理方式也很明 ...