标准窗口函数
| 功能 | 是否支持? |
|---|---|
即席窗口定义 (count(*) over (partition by id order by time desc)) | ✅ |
包含窗口函数的表达式,例如 (count(*) over ()) / 2 | ✅ |
WINDOW 子句 (select ... from table window w as (partition by id)) | ✅ |
ROWS 窗口帧 | ✅ |
RANGE 窗口帧 | ✅ (默认) |
用于 DateTime RANGE OFFSET 窗口帧的 INTERVAL 语法 | ❌ (请改为指定秒数 (RANGE 适用于任何数值类型) 。) |
GROUPS 窗口帧 | ❌ |
在窗口帧上计算聚合函数 (sum(value) over (order by time)) | ✅ (支持所有聚合函数) |
rank(), dense_rank(), row_number() | ✅ 别名: denseRank() |
percent_rank() | ✅ 高效计算某个值在数据集分区中的相对排名。该函数可有效替代更冗长且计算开销更高的手动 SQL 写法,即 ifNull((rank() OVER(PARTITION BY x ORDER BY y) - 1) / nullif(count(1) OVER(PARTITION BY x) - 1, 0), 0) 别名: percentRank() |
cume_dist() | ✅ 计算某个值在一组值中的累积分布。返回值小于或等于当前行值的行所占的百分比。 |
lag/lead(value, offset) | ✅ 你也可以使用以下任一替代方案: 1) any(value) over (.... rows between <offset> preceding and <offset> preceding),或者对 lead 使用 following 2) lagInFrame/leadInFrame,它们与之类似,但会遵循窗口帧。若要获得与 lag/lead 完全相同的行为,请使用 rows between unbounded preceding and unbounded following |
| ntile(buckets) | ✅ 例如,可按如下方式指定窗口: (partition by x order by y rows between unbounded preceding and unbounded following)。 |
ClickHouse 特有的窗口函数
以下是 ClickHouse 特有的窗口函数:nonNegativeDerivative(metric_column, timestamp_column[, INTERVAL X UNITS])
根据timestamp_column 计算给定 metric_column 的非负导数。
INTERVAL 可省略,默认为 INTERVAL 1 SECOND。
各行的计算值如下:
- 第 1 行为
0, - 第 行为 。
语法
PARTITION BY- 定义如何将结果集划分为多个组。ORDER BY- 定义在计算 aggregate_function 时,如何对组内的行进行排序。ROWS or RANGE- 定义窗口帧的边界,aggregate_function 在窗口帧内进行计算。WINDOW- 允许多个表达式使用同一个窗口定义。
函数
row_number()- 对当前行在其分区内从 1 开始编号。first_value(x)- 返回其有序窗口帧内计算得到的第一个值。last_value(x)- 返回其有序窗口帧内计算得到的最后一个值。nth_value(x, offset)- 返回其有序窗口帧中第 n 行 (offset) 计算得到的第一个非 NULL 值。rank()- 对当前行在其分区内进行有间隔排名。dense_rank()- 对当前行在其分区内进行无间隔排名。lagInFrame(x)- 返回其有序窗口帧内当前行之前按指定物理偏移量对应行上计算得到的值。leadInFrame(x)- 返回其有序窗口帧内当前行之后偏移若干行处计算得到的值。
示例
为行编号
聚合函数
按列分区
窗口帧边界
真实场景示例
各部门的最高/总工资
累积和
移动平均 / 滑动平均 (每 3 行)
移动平均 / 滑动平均 (每 10 秒)
移动平均 / 滑动平均 (每 10 天)
Range 和 ORDER BY toDate(ts),我们构造了一个大小为 10 个单位的窗口帧;而由于使用了 toDate(ts),这里的单位就是天。