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的字段必须建有索引,也可以为索引的一部分.当没有索引时会报错: ...
随机推荐
- Appium 入门
Appium安装总体需要以下几个步骤: 安装JDK 官网www.oracle.com去下载安装,尽量下载JDK7及以上的版本.然后去设置环境变量: 在系统变量下新建变量JAVA_HOME变量值指向JD ...
- 浅谈dfs深度优先搜索
深度优先搜索(Depth First Search)是一种常见的暴力算法 此算法上限和下限较高,容易上手,适用情形多,学习性价比高 下限高于有固定的模板,且时间复杂度明显优于暴力枚举,容易拿到题目部分 ...
- ARM的发展史以及架构解析
本文从ARM的发展历史着手,以S3C2440为例与51单片机进行对比分析,详细解析了ARM架构. 先来谈一下ARM的发展史:1978年12月5日,物理学家Hermann Hauser和工程师Chris ...
- XenForo论坛安装
1.下载安装程序,程序可以到qq群里面找,或者是联系我 2.域名+/install安装 3.汉化后台,访问https://www.cnxfans.com/resources/xenforo-2-x.1 ...
- vue相关组件用法
<el-checkbox v-model="checkbox.checkModel" :label="index":disabled="chec ...
- js获取对象数组中指定属性值的新数据
例: let arr = [ {name: "name1", age: "1",type:"1"}, {name: "name2& ...
- OM6621P系列国产M4F内核低功耗BLE5.1 SoC蓝牙芯片
随着5G与物联网时代到来,智慧城市.电动出行.智能家居.可穿戴设备等应用高速发展,低功耗蓝牙技术在近几年智能化浪潮中的地位也尤为重要.OM6621P系列的开发即是为解决国内低功耗蓝牙应用设计需求,其主 ...
- M1 安装apache tomcat
一.下载以及安装 1.Tomcat(官网:http://tomcat.apache.org/) 2.找到需要的版本:我用的9版本 二.将下载的文件放在自己一个目录下去 三.设置Apache环境路径 e ...
- Java 并发线程池线程数配置
1. 如果任务是计算密集型的,线程池大小建议设置为Ncpu + 1 其中N是CPU数量, +1 是为了在某一个线程处于暂停阶段时,有新的线程可以用来执行,减少CPU中断时间. 2. 如果是IO密集型, ...
- Zookeeper ZAB协议-Leader&Followe 对象创建和启动源码解析
这篇博客主要是解析了Leader,Follower 对象的创建,相对来说比较简单,主要是了解一下在实例化的时候创建了哪些对象,这些对象会在数据传输的过程中发挥比较打的作用,如果有了解过的,可以直接跳过 ...