You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UNBOUNDED PRECEDING与当前行窗口框架的工作原理剖析

窗口函数ORDER BY默认框架的行为疑问

测试数据

CREATE SCHEMA test_schema;
CREATE TABLE test_schema.joinedDf(id LONG, firstName TEXT, lastName TEXT, age INT, month INT, salary DECIMAL);

INSERT INTO test_schema.joinedDf(id, firstName, lastName, age, month, salary) VALUES
(1111, 'Peter', 'Ivanov', 29, 10, 300000),
(1111, 'Peter', 'Ivanov', 29, 12, 350000),
(1111, 'Peter', 'Ivanov', 29, 11, 350000);

查询1:指定全窗口范围

执行查询:

SELECT id, firstName, lastName, age, month, salary,
AVG(salary) OVER (PARTITION BY id ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) average_salary
FROM test_schema.joinedDf;

得到结果:

1111, Peter, Ivanov, 29, 10, 300000, 333333.3333
1111, Peter, Ivanov, 29, 12, 350000, 333333.3333
1111, Peter, Ivanov, 29, 11, 350000, 333333.3333

查询2:仅指定ORDER BY的默认窗口

执行查询:

SELECT id, firstName, lastName, age, month, salary,
AVG(salary) OVER (PARTITION BY id ORDER BY salary) average_salary
FROM test_schema.joinedDf;

得到结果:

1111, Peter, Ivanov, 29, 10, 300000, 300000.0000
1111, Peter, Ivanov, 29, 12, 350000, 333333.3333
1111, Peter, Ivanov, 29, 11, 350000, 333333.3333

疑问

已知PARTITION BY中指定ORDER BY时,默认窗口框架为UNBOUNDED PRECEDING AND CURRENT ROW,但为什么结果不是预期的逐步累加计算:

1111, Peter, Ivanov, 29, 10, 300000, 300000.0000
1111, Peter, Ivanov, 29, 12, 350000, 325000.0000
1111, Peter, Ivanov, 29, 11, 350000, 333333.3333

原因解释

核心问题在于默认窗口框架的模式是RANGE而非ROWS:

  • 当窗口函数仅指定ORDER BY而未显式声明框架模式时,SQL标准默认使用RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,而不是ROWS模式。
  • RANGE模式下,窗口范围是基于排序键的逻辑值:所有排序键值小于等于当前行排序键值的行都会被包含在窗口内,而不是仅到物理上的当前行。
  • 在你的数据中,有两行salary=350000,它们的排序键值相同。因此,当计算这两行的窗口平均值时,窗口会包含所有salary<=350000的行(也就是全部3行),所以平均值为(300000+350000+350000)/3=333333.3333。

如何得到预期的逐步计算结果

如果想要按照物理行顺序逐行累加计算平均值,需要显式指定ROWS模式的窗口框架:

SELECT id, firstName, lastName, age, month, salary,
AVG(salary) OVER (PARTITION BY id ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) average_salary
FROM test_schema.joinedDf;

此时执行结果会符合你预期的逐步累加:

1111, Peter, Ivanov, 29, 10, 300000, 300000.0000
1111, Peter, Ivanov, 29, 12, 350000, 325000.0000
1111, Peter, Ivanov, 29, 11, 350000, 333333.3333

内容的提问来源于stack exchange,提问作者Pavel Orekhov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 14:14:53