窗口函数基于结果集进行计算,将计算出的结果合并到输出的结果集上,并返回多行。使用窗口函数能大幅度简化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. desginer启动就直接卡死

    博主经验: 请不要开有道词典    请不要开有道词典         请不要开有道词典

  2. docker-compose任务编排

    一.docker-compose介绍 使用一个Dockerfile模板文件可以定义一个单独的应用容器,如果需要定义多个容器就需要服务编排.下面介绍Docker官方产品,Docker Compose. ...

  3. C#如何判断文件是否存在

    https://jingyan.baidu.com/article/ac6a9a5ead6ef86b653eac8b.html 首先,我们定义一个字符串,名为path. 然后,我们给他一个路径,这样才 ...

  4. springboot启动报错 Failed to scan *****/derbyLocale_ja_JP.jar from classloader hierarchy

    springboot启动报错 Failed to scan *****/derbyLocale_ja_JP.jar from classloader hierarchy   这两天自己在玩虚拟机,想把 ...

  5. 记录一次在deepin安装node版本管理工具nvm的过程

    安装nvm sudo apt-get install git -y # 安装git cd /home # 随便找个目录放代码 git clone https://github.com/nvm-sh/n ...

  6. centos8使用kubeadm搭建高可用k8s集群

    kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点 kubeadm ini ...

  7. Raid磁盘阵列更换磁盘时另一块盘离线恢复案例(v7000存储数据恢复)

    Raid磁盘阵列更换磁盘时另一块盘离线恢复案例(v7000存储数据恢复) [故障描述]客户设备型号为IBM V7000存储,架构为AIX+oracle+V7000存储阵列柜,需要恢复的数据主要存放在阵 ...

  8. c语言动态库与静态库

    // show.h #ifndef __SHOW_H_ #define __SHOW_H_ #include <stdio.h> #include "math.h" v ...

  9. 【运维】解决composer update出现的Discard changes [y,n,v,d,s,?]的问题

    在PHP项目中,composer是一个使用非常普遍的包管理工具,在本地开发的时候出现了这个问题一搬来说问题不大,可以人为进行输入交互,但是如果是自动化发布中出现,就会等待输入导致卡住,是一个需要解决的 ...

  10. system verilog与C语言的接口(包含使用方法以及实例)

    资料来源 (1) sv绿皮书; (2) vcs user guide; (3) https://www.cnblogs.com/studyforever/p/5169243.html (4) syst ...