PostgreSQL 窗口函数 ( Window Functions ) 如何使用?
一、为什么要有窗口函数
我们直接用例子来说明,这里有一张学生考试成绩表testScore:

现在有个需求,需要查询的时候多出一列subject_avg_score,为此科目所有人的平均成绩,好跟每个人的成绩做对比。
传统方法肯定是用聚合,但是写起来很麻烦也很累赘,这时候窗口函数就排上了用场。
因为窗口函数不会像聚合一样将参与计算的行合并成一行输出,而是将计算出来的结果带回到了计算行上。
二、窗口函数的使用
1、聚合和窗口函数的区别
聚合:聚合函数(sum,min,avg……) + GROUP BY
窗口函数:聚合函数(sum,min,avg……) + OVER ( …… )
2、使用
还用上面的例子:
(1) 取每个不同科目的平均值subject_avg_score [这正是上面提到的需求]
这里的 OVER 里用到了 PARTITION BY
SELECT *,
avg("score") OVER (PARTITION BY "subject") as "subject_avg_score"
FROM "testScore"

(2) 取所有成绩的平均值subject_avg_score
这里的 OVER 里为空
SELECT *,
avg("score") OVER () as "subject_avg_score"
FROM "testScore"

(3) 取此人该科目成绩班上排第几名subject_rank_score
这里的 OVER 里用到了 PARTITION BY + ORDER BY
ORDER BY 只能用在一些特殊的聚合函数里,比如这里的 rank()
SELECT *,
avg("score") OVER (PARTITION BY "subject") as "subject_avg_score",
rank() OVER (PARTITION BY "subject" ORDER BY "score" DESC) as "subject_rank_score"
FROM "testScore"

拓展知识:rank()、dense_rank()、row_number() 区别
rank() 最适合用来做排名的功能,它是若两人并列第一,那第三个人就排名第三
dense_rank() 跟 rank() 的区别是,若两人并列第一,那第三个人紧随其后排名第二
row_number() 则单纯是序号,所以不会出现多个人并列的情况。
(4) 提取 OVER 变量
如果在 sql 里写了很多重复的 OVER(),可以提取成一个 window 变量,简化代码。
SELECT *,
avg("score") OVER window_frame as "subject_avg_score",
avg("score") OVER window_frame as "subject_avg_score_2",
avg("score") OVER window_frame as "subject_avg_score_3"
FROM "testScore"
window window_frame as (PARTITION BY "subject")

参考资料
官方文档:http://www.postgres.cn/docs/9.3/tutorial-window.html
PostgreSQL 窗口函数 ( Window Functions ) 如何使用?的更多相关文章
- 16. 窗口函数 (Window Function) 的使用
从SQL Server 2005起,SQL Server开始支持窗口函数 (Window Function),以及到SQL Server 2012,窗口函数功能增强,目前为止支持以下几种窗口函数: 1 ...
- MySQL 8.0.2: Introducing Window Functions
July 18, 2017MySQL, SQLDag Wanvik MySQL 8.0.2 introduces SQL window functions, or analytic functions ...
- PostgreSQL>窗口函数的用法
PostgreSQL之窗口函数的用法 转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9311281.html PostgreSQL的高级特性本准备三篇的(递归. ...
- PostgreSQL窗口函数(转)
转自:http://time-track.cn/postgresql-window-function.html PostgreSQL提供了窗口函数的特性.窗口函数也是计算一些行集合(多个行组成的集合, ...
- SQL Server Window Function 窗体函数读书笔记二 - A Detailed Look at Window Functions
这一章主要是介绍 窗体中的 Aggregate 函数, Rank 函数, Distribution 函数以及 Offset 函数. Window Aggregate 函数 Window Aggrega ...
- PostgreSQL窗口函数
窗口函数允许在查询的SELECT列表和ORDER BY子句中使用. 如果有排序,要保证唯一,否则会有下面的错误: 修改方式是:保证唯一,修改方法如下:
- postgresql 窗口函数排序实例
经常遇到一种应用场景,将部分行的内容进行汇总.比较.排序. 比如数据表名称test.test2 select num,province from test.test2 得到结果: ;"黑龙江 ...
- 《SQL基础教程》+ 《SQL进阶教程》 学习笔记
写在前面:本文主要注重 SQL 的理论.主流覆盖的功能范围及其基本语法/用法.至于详细的 SQL 语法/用法,因为每家 DBMS 都有些许不同,我会在以后专门介绍某款DBMS(例如 PostgreSQ ...
- Flink 的Window 操作(基于flink 1.3描述)
Window是无限数据流处理的核心,Window将一个无限的stream拆分成有限大小的”buckets”桶,我们可以在这些桶上做计算操作.本文主要聚焦于在Flink中如何进行窗口操作,以及程序员如何 ...
随机推荐
- Mysql数据库表的自增主键ID号乱了,需要重新排列。
Mysql数据库表的自增主键ID号乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键:ALTER TABLE `table_name` DROP `id`; 2, ...
- laravel在wamp中输入地址后总是无法访问
在wamp中的apache中conf的httpd.conf #LoadModule rewrite_module modules/mod_rewrite.so 改为 LoadModule rewrit ...
- PySide——Python图形化界面入门教程(六)
PySide——Python图形化界面入门教程(六) ——QListView和QStandardItemModel 翻译自:http://pythoncentral.io/pyside-pyqt-tu ...
- dotnet core 跨平台编译发布
vs2017 建立的项目,在项目目录 ,执行 dotnet publish -r ubuntu.15.04-x64 dotnet publish -r linux-x64 dotnet publish ...
- 微信小程序把玩(十一)icon组件
原文:微信小程序把玩(十一)icon组件 这些是提供的所支持的图标样式,根据需求在此基础上去修改大小和颜色. 主要属性: 使用方式: wxml <!--成功图标--> <icon t ...
- 简析TCP的三次握手与四次分手(TCP协议头部的格式,数据从应用层发下来,会在每一层都会加上头部信息,进行封装,然后再发送到数据接收端)good
2014-10-30 分类:理论基础 / 网络开发 阅读(4127) 评论(29) TCP是什么? 具体的关于TCP是什么,我不打算详细的说了:当你看到这篇文章时,我想你也知道TCP的概念了,想要更 ...
- 为什么你有10年经验,但成不了专家?(重复性刻意训练+反馈修正,练习的精髓是要持续地做自己做不好的,太精彩了)真正的高手都有很强的自学能力,老师和教练的最重要作用是提供即时的反馈(莫非我从小到大学习不好的原因在这里?没有单独刻意训练?) good
也许简单看书就是没有刻意训练.更没有反馈,所以没有效果 我倒是想起自己,研究VCL源码的时候,都是自己给自己提问,然后苦思冥想.自己解决问题,然后Windows编程水平果然上了一个台阶.对什么叫做“框 ...
- XP系統IIS最大連接數修改
方法一: 安裝軟件 http://download.microsoft.com/download/iis50/Utility/5.0/NT45/EN-US/MtaEdt22.exe 然後進入 W3S ...
- hive Metastore contains multiple versions
凌晨接到hive作业异常,hive版本为1.2.1,hadoop版本apache 2.7.1,元数据存储在mysql中,异常信息如下: Logging initialized using config ...
- flask(四)
1.Flask-Session from flask import session,Flask from flask_session import Session #导入 from redis imp ...