SQL 分窗函数

本文详细介绍了SQL中的窗函数概念及其应用,包括为什么要使用窗函数、窗函数的基本语法、常用的窗函数类型(如RANK(), DENSE_RANK(), ROW_NUMBER()等)、如何使用滑动窗口进行计算,以及一些具体的案例分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文来源于“mysql分窗函数_SQL 窗函数”、“SQL学习笔记 - 窗口函数OVER”两篇文章,有侵犯可直接联系作者删除。

一、为什么需要窗函数?

既要对数据进行分组,又要对每个组进行某种聚合运算,同时还要对每行输出对应的聚合运算的结果(用 group by 很难实现)。举例:

有一组数据,包含以下字段:城市,姓名,年龄,性别。需求是找出同龄人以及城市人数,按照如下格式输出:城市,姓名,年龄,性别,人数,同龄人人数。

二、什么是窗函数?

窗口函数是 SQL 中一类特别的函数。和聚合函数相似,窗口函数的输入也是多行记录。不同的是,聚合函数的作用于由 GROUP BY 子句聚合的组,而窗口函数则作用于一个窗口, 这里,窗口是由一个 OVER 子句 定义的多行记录。

聚合函数对其所作用的每一组记录输出一条结果,而窗口函数对其所作用的窗口中的每一行记录输出一条结果。

  • Perform calculations on an already generated result set ( a window).(在已生成的结果集上执行计算)
  • Aggregate calculation(without having to group your data)(允许使用聚合函数时不用进行GROUP BY分组)
  • Similar to subqueries in SELECT. (类似于 SELECT 中的子查询)
  • Running totals, rankings, and moving averages, etc.(可计算累加值,排序,移动平均值等)
  • Processed after every part of query except ORDER BY.(执行顺序在其他各部分之后,但在ORDER BY 之前)
  • Uses information in result set rather than database.(使用结果集中的数据而非数据库)
  • Available in PostgreSQL, Oracle, MySQL, SQLServer, and SQLite.(适用于 PostgreSQLOracleMySQLSQLServer SQLite

其他说法

  • 窗口函数是在所有JOINWHEREGROUP BYHAVING子句之后以及ORDER BYLIMITSELECT DISTINCT之前的结果集上执行的

三、语法

FUNCTION(value) OVER ([PARTITION BY field] [ORDER BY field]
 [ROWS BETWEEN <start> AND <finish>])
注:[]中的内容可省略,根据实际情况选择使用。

PARTITION BY (分区定义): range of calculation根据指定(1个或多个)字段进行分区,类似GROUP BY。partition_clause将行分成块或分区。两个分区由分区边界分隔。窗口功能在分区内执行,并在跨越分区边界时重新初始化。此外不同的 partition by 是互不影响的,比如上面那道题,可以同时写

COUNT(*)OVER(partition by age)

COUNT(*)OVER(partition by city)

ORDER BY(顺序定义) : order of rows when running calculation 根据指定字段进行排序

ROWS BETWEEN AND (框架定义):滑动窗口

四、常用函数

4.1 专用窗口函数

RANK():计算排序,如果存在相同位次的记录,为相同的值分配相同的数字,但会跳过之后的位次。

DENSE_RANK():同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次。

ROW_NUMBER() :从1开始,返回每组内部排序后的顺序编号(组内连续的唯一的)

SELEECT 
  goals,
  RANK() OVER(ORDER BY goals DESC) AS goals_rank,
  DENSE_RANK() OVER(ORDER BY goals DESC) AS goals_dense_rank,
  ROW_NUMBER() OVER(ORDER BY goals DESC) AS row_number 
FROM grade
ORDER BY goals DESC;

结果如下:

goalsgoals_rankgoals_dense_rankrow_number
10111
10112
9323
9324
7535

LAG(column, n):returns column's value at the row n rows before the current row. 返回当前行之前第n行的值(n省略时默认为1,表示返回当前行前1行的值)。

LEAD(column, n) : returns column's value at the row n row after the current row. 返回当前行之后第n行的值。

FIRST_VALUE(column):return the first value in the table or partition. 返回表中或分区中第一个值。

LAST_VALUE(column):return the last value in the table or partition. 返回表中或分区中最后一个值。

NTILE(n):splits data into n approximately equal pages. 将数据分为近乎相等的n等份(比如由于数据量大,需要将数据平均分配到n个并行的进程分别计算,此时就可以用到该函数)。

4.2 聚合函数

SUM, AVG, COUNT, MAX, MIN 也可以用于窗口函数。

4.3 滑动窗口(Sliding Window)

In addition to calculating aggregate and rank information, window functions can also be used to calculate information that changes with each subsequent row in a data set. These types of window functions are called sliding windows.除了计算汇总、聚合和排序等,窗口函数还可以用于计算随数据集中的每个后续行而变化的信息。这类窗口功能称为滑动窗口。

Sliding windows are functions that perform calculations relative to the current row of a data set. 滑动窗口是执行相对于数据集当前行的计算的功能。

You can use sliding windows to calculate a wide variety of information that aggregates one row at a time down your data set -- running totals, sums, counts, and averages in any order you need. 您可以使用滑动窗口来计算各种各样的信息,这些信息在您的数据集中一次聚合一行——按您需要的任何顺序运行总计、总和、计数和平均值。

A sliding window calculation can also be partitioned by one or more column just like a non-sliding window. 滑动窗口计算也可以像非滑动窗口一样按一列或多列进行分区。

ROWS BETWEEN <start> AND <finish>

可用于start 和finish 的关键字有:

  • PRECEDING : n PRECEDING means n rows before the current row 当前行的之前第n
  • FOLLOWING : n FOLLOWING means n row after the current row 当前行之后的第n
  • UNBOUNDED PRECEDING : every row since the beginning of the data set 数据集的开始
  • UNBOUNDED FOLLOWING : every row to the end of the data set 数据集的末尾
  • CURRENT ROW : tells SQL that you want to stop your calculation at the current row 当前行

五、其他案例

Hive窗口函数 over()详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值