Skip to main content
窗口函数可让你对与当前行相关的一组行进行计算。 它们可用于执行与聚合函数类似的计算,但不同之处在于,窗口函数不会将多行分组成单个输出,而是仍会返回各个行。

标准窗口函数

ClickHouse 支持窗口和窗口函数的标准 SQL 语法。 下表展示了当前支持的功能:

语法

  • PARTITION BY - 定义如何将结果集划分为多个组。
  • ORDER BY - 定义在计算 aggregate_function 时,如何对组内的行进行排序。
  • ROWSRANGEGROUPS - 定义窗口帧的边界,aggregate_function 在窗口帧内进行计算。ROWS 按物理行计数,RANGEORDER BY 值计数,GROUPS 按对等组计数 (即 ORDER BY 键值相等的行) 。
  • WINDOW - 允许多个表达式使用同一个窗口定义。

仅可作为窗口函数使用的函数

以下函数只能作为窗口函数使用。其中大多数是标准 SQL 函数;lagInFrameleadInFramenonNegativeDerivative 是 ClickHouse 扩展。

示例

下面来看一些窗口函数的使用示例。

为行编号

聚合函数

将每位球员的薪资与其所在球队的平均薪资进行比较。
比较每位球员的薪资与其所在球队的最高薪资。

按列分区

窗口帧界定

GROUPS 窗口帧

GROUPS 窗口帧以完整的对等组为单位计数——即 ORDER BY 键相同的行集合——而非物理行 (ROWS) 或 ORDER BY 值 (RANGE) 。N PRECEDINGN FOLLOWING 分别表示当前行所属对等组之前和之后的 N 个对等组;每个纳入窗口的对等组均包含其所有行。 以下查询针对 ROWSRANGEGROUPS 窗口帧,均使用相同的 1 PRECEDING AND 1 FOLLOWING 边界。order 列包含重复且不连续的值,因此这三种模式覆盖的行各不相同:
每种模式对边界的解释方式不同:
  • ROWS 按物理行计数,因此窗口帧最多包含三个相邻行:当前行及其前后各一行。
  • RANGEorder 值计数,因此 1 PRECEDING1 FOLLOWING 覆盖与当前行 order 值相差不超过 1 的行。当间隔为 10 时,没有相邻行符合条件,因此窗口帧仅包含与当前行具有相同 order 值的行。
  • GROUPS 按对等组计数,因此 1 PRECEDING1 FOLLOWING 始终完整包含相邻组,无论 order 值之间的间隔有多大。

真实场景示例

以下示例用于解决常见的实际问题。

各部门的最高/总工资

累积和

移动平均 / 滑动平均 (每 3 行)

移动平均 / 滑动平均 (每 10 秒)

移动平均 / 滑动平均 (每 10 天)

温度以秒级精度存储,但使用 RangeORDER BY toDate(ts) 时,我们构造出的窗口帧大小为 10 个单位;而由于使用了 toDate(ts),这里的单位是天。

参考资料

GitHub Issues

有关窗口函数初步支持的路线图,请参见此 issue 所有与窗口函数相关的 GitHub issue 都带有 comp-window-functions 标签。

测试

这些测试包含当前已支持语法的示例: https://github.com/ClickHouse/ClickHouse/blob/master/tests/performance/window_functions.xml https://github.com/ClickHouse/ClickHouse/blob/master/tests/queries/0_stateless/01591_window_functions.sql

Postgres 文档

https://www.postgresql.org/docs/current/sql-select.html#SQL-WINDOW https://www.postgresql.org/docs/devel/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS https://www.postgresql.org/docs/devel/functions-window.html https://www.postgresql.org/docs/devel/tutorial-window.html

MySQL 文档

https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html https://dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html https://dev.mysql.com/doc/refman/8.0/en/window-functions-frames.html
最后修改于 2026年8月14日