窗口函数基于结果集进行计算,将计算出的结果合并到输出的结果集上,并返回多行。使用窗口函数能大幅度简化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 窗口函数的更多相关文章

  1. 专访探探DBA张文升:PG在互联网应用中同样也跑的很欢畅

    张文升认为,PG无论在可靠性和性能方面都不输其它任何关系型数据库   张文升,探探DBA,负责探探的数据库架构.运维和调优的工作.拥有8年开发经验,曾任去哪儿网DBA.   9月24日,张文升将参加在 ...

  2. 数据库周刊31丨openGauss 正式开源;7月数据库排行榜发布;浙江移动国产数据库AntDB迁移;oracle ADG跨版本搭建;PG解决社保问题;mysqlbinlog解析……

    摘要:墨天轮数据库周刊第31期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.openGauss 正式开源,华为公开发布源代码[摘要]6月1日,华为正式宣布开源数据库能 ...

  3. 简析服务端通过GT导入SHP至PG的方法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 项目中需要在浏览器端直接上传SHP后服务端进行数据的自动入PG ...

  4. PG 中 JSON 字段的应用

    13 年发现 pg 有了 json 类型,便从 oracle 转 pg,几年下来也算比较熟稔了,总结几个有益的实践. 用途一:存储设计时无法预料的文档性的数据.比如,通常可以在人员表准备一个 json ...

  5. pg gem 安装(postgresql94)

    使用下面命令安装报错 gem install pg 错误: [root@AS-test middle_database]# gem install pgBuilding native extensio ...

  6. #pg学习#postgresql的安装

    1.按照官网给的步骤编译安装(Mac安装是比较容易的,相比Liunx) cd /Users/renlipeng/Desktop/postgresql-9.5.1 ./configure --prefi ...

  7. Over:窗口函数(滑动聚合)

    Over 窗口函数在Select 子句中,对查询的结果集进行“滑动-聚合”运算:如果使用count,那么基于滑动窗口的聚合语义同 base+1 累加:如果使用sum,那么基于滑动窗口的聚合语义等同于数 ...

  8. SQL Server中的窗口函数

    简介     SQL Server 2012之后对窗口函数进行了极大的加强,但对于很多开发人员来说,对窗口函数却不甚了解,导致了这样强大的功能被浪费,因此本篇文章主要谈一谈SQL Server中窗口函 ...

  9. PG 函数的易变性(Function Volatility Categories)

    此概念的接触是在做分区表的时候碰到的,分区表按时间字段分区,在查询时当where条件中时间为now()或者current_time()等时是无法查询的,即使进行格式转换也不行,只有是时间格式如‘201 ...

  10. mysql 序列与pg序列的比较

    mysql序列(这里只谈innodb引擎): 在使用mysql的AUTO_INCREMENT时,使用AUTO_INCREMENT的字段必须建有索引,也可以为索引的一部分.当没有索引时会报错:      ...

随机推荐

  1. linux 高并发系统限制 设置

    linux资源限制配置文件是/etc/security/limits.conf:限制用户进程的数量对于linux系统的稳定性非常重要. limits.conf文件限制着用户可以使用的最大文件数,最大线 ...

  2. ssgvip设置

    ssgvip.tpl set service "{vipport}" protocol {xieyi} src-port 0-65535 dst-port {vipport}-{v ...

  3. GET请求数据量大造成的问题

    在实际的开发过程中,我们偶尔或者遇到过要导出列表中所有的数据.假设列表中有十万条数据,那么导出所有,意味着要大批量的走查询接口,通常我们的后台的API接口GET请求支持的查询长度不得大于1000,(比 ...

  4. Selenium私房菜系列7 -- 深入了解Selenium RC工作原理(2)【II】

    继续前一篇的问题,为什么Selenium RC中的Selenium Server需要以这种代理服务器的形式存在?其实,这和浏览器的"同源策略"(The Same Origin Po ...

  5. mybatis中xml新增一条数据获取自增id

    在insert的标签里加两个属性:useGeneratedKeys="true"         keyProperty="patentId"   ,这个key ...

  6. 解决在Android studio的Button控件下background背景设置不起作用的问题

    Button控件默认的背景是深紫色的,有时候会看不清按钮上的文本,显得很不方便,想要修改背景色所以添加了background字段,但是又不起作用!!! 1.找到values文件夹下面的themes文件 ...

  7. 【Pr】如何裁剪视频得页面?

    [Pr]如何裁剪视频得页面? 选择视频轨道 | 效果 | 裁剪(可以搜索) | 调整上下左右需要裁剪的大小 | 选择缩放,去掉黑边

  8. java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'

    你设置的主键里面已经有一个值为1的数值了,再插入一个就重复了. 但是主键是不能重复的.

  9. 最小化安装debian10&gnome最小化安装

    直到后面配置网络源之前都是断网安装,因为debian security好像总是要去总源找点东西,所以即便你选择国内源甚至不选择网络源安装,依然会莫名 的失败. I. 最小化安装debian10(用ro ...

  10. 斐讯K2_V22.6.507.43降级+刷机整个过程

    K2刷机整个过程 (包括降级) 开始之前请先下载好相对应的工具包,其中包括: 官方固件:"K2_V22.6.506.28.bin"."K2_V22.6.507.43.bi ...