ClickHouse窗口函数last_value详解与应用
什么是last_value函数
last_value是ClickHouse提供的一个窗口函数,用于返回当前窗口框架内的最后一个值。与常规聚合函数不同,窗口函数不会将多行合并为单行结果,而是为每一行返回一个计算结果,同时保留原始行的所有列。
函数语法
last_value(column_name) [[RESPECT NULLS] | [IGNORE NULLS]]
OVER (
[PARTITION BY grouping_column]
[ORDER BY sorting_column]
[ROWS | RANGE frame_definition]
)
参数说明
column_name:要获取最后值的列名RESPECT NULLS:可选修饰符,表示包含NULL值IGNORE NULLS:可选修饰符,表示跳过NULL值(默认行为)PARTITION BY:定义窗口分区,相同分组值的行会被划分到同一个窗口ORDER BY:定义窗口内的排序规则ROWS/RANGE:定义窗口框架的范围
函数特性
- 默认行为:默认情况下,last_value会跳过NULL值
- NULL处理:使用
RESPECT NULLS可以强制包含NULL值 - 别名:该函数有两个别名:
anyLast和lastValueRespectNulls - 窗口框架:如果没有指定窗口框架,默认使用
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
实际应用示例
基础示例:查找薪资最低的球员
假设我们有一个英超球员薪资表:
CREATE TABLE salaries (
`team` String,
`player` String,
`salary` UInt32,
`position` String
) Engine = Memory;
插入示例数据后,我们可以使用last_value找出薪资最低的球员:
SELECT
player,
salary,
last_value(player) OVER (
ORDER BY salary DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS lowest_paid_player
FROM salaries;
结果将显示每行记录以及整个结果集中薪资最低的球员姓名。
高级用法:分区计算
我们还可以按球队分组,找出每个球队中薪资最低的球员:
SELECT
team,
player,
salary,
last_value(player) OVER (
PARTITION BY team
ORDER BY salary DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS team_lowest_paid_player
FROM salaries;
注意事项
- 性能考虑:窗口函数在处理大数据集时可能消耗较多资源,应合理使用
- 框架定义:明确指定窗口框架范围可以获得更精确的结果
- NULL处理:根据业务需求决定是否包含NULL值
- 排序影响:ORDER BY子句的排序方向会影响last_value的结果
与其他函数的对比
- first_value:获取窗口框架内的第一个值
- nth_value:获取窗口框架内指定位置的值
- lag/lead:获取相对于当前行的前/后指定偏移量的值
last_value函数在数据分析中非常有用,特别是在需要获取分组内最后一个值或边界值的场景下。通过合理使用窗口定义和排序规则,可以解决许多复杂的数据分析问题。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



