窗口函数基于结果集进行计算,将计算出的结果合并到输出的结果集上,并返回多行。使用窗口函数能大幅度简化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. Android中动态添加tab

    来源过于啰嗦,这里只有简化后的. 转载请注明出处  http://www.cnblogs.com/zaiyuzhong/p/add-tab-dynamic-in-android.html 建立对应的布 ...

  2. kumquat

    今天准备做个解释型编程语言,名字就叫kumquat(金桔)因为我刚刚喝了口金桔柠檬茶,挺甜的 用python写把

  3. zabbix编译安装,安装mysql数据库:configure: error: Not found mysqlclient library

    在编译时,可能会出现题目中所示的错误,可以通过安装mysql-devel这个库解决: # yum install mysql-devel 注:如果出现"configure: error : ...

  4. linux 安装简洁的 zsh

    为什么要安装简洁的 zsh zsh 是 shell 中的佼佼者,但是网上配置 zsh的方案,千篇一律的都是配置的 oh-my-zsh,个人感觉非常臃肿,配置低的话,用起来还会非常卡. 安装 zsh 本 ...

  5. Windows10+VS2019从源码编译 Qt5

    参考 Windows10+MSVC(VS2022)从源码编译QT5.12.11 - 知乎 (zhihu.com) qt-labs/vstools ~ qt-labs/vstools (github.c ...

  6. supertv

    Banben:1.3BanbenendGengxinnr:死宅1.2更新内容:[换行]- 增加视频分享[换行]- 支持浏览器打开观看视频GengxinnrendDownurl:http://bmob- ...

  7. iOS笔记 - Runtime 01:前期准备(isa结构 | Class结构 | 方法缓存)

    前言 1 - OC机制很多都是基于 Runtime实现的,比如指针的弱引用.OC的消息机制属于 Runtime的一部分 2 - OC是一门动态语言,在程序运行过程中就可以修改已经编译好的代码 3 -  ...

  8. docker的安装和命令

    一. 认识Docker 我们写的代码会接触好几个环境:开发环境,测试环境以及生产环境 开发环境:程序员开发代码的环境 测试环境:开发完的代码部署到测试环境 给测试人员进行测试 生产环境:测试完成后有运 ...

  9. Tushare金融大数据开放社区 - 数据抽取案例学习

    进入平台介绍 扫码立即注册,更多大数据等你来探索 ! 案例: 导入tushare import tushare as ts 这里注意, tushare版本需大于1.2.10 设置token ts.se ...

  10. YieldReturn语法解析

    /* * * 学习Yield Return 语法 * 使用两个方法,显示1 - 100之间的全部偶数 * * */ using System;using System.Collections.Gene ...