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

SQL使用ROWS BETWEEN子句分组计算滚动均值的方案正确性验证

结论

你的实现逻辑不对,有两个核心问题,跑出来的结果不符合需求:

第一个问题:窗口排序规则完全错了

你给窗口函数写的排序规则是ORDER BY var_1 DESC,相当于把同一个id下的行按var_1的值倒序排,所有值为1的行堆在前面,值为0的堆在后面,直接打乱了观测的原始先后顺序。你要算的是「最近N条观测」的均值,这种排法算出来的滚动值根本和观测顺序无关,完全是错的。
要注意SQL表本身是无序的,要定义「最近」必须有明确的先后标识字段,比如你示例里最左侧1到20的行序号、观测入库的时间戳这类字段,窗口排序必须用这类字段,才能保证取到的是按时间/录入顺序的最近N条。

第二个问题:全组均值的实现太冗余

你要的var_1_lag_all是同id下所有var_1的平均值,根本不需要单独建中间表分组聚合再左连,窗口函数直接就支持:只要分区后不写自定义行范围,默认统计范围就是同分区的所有行,单条SQL就能算完,省掉建中间表、多表关联的额外开销。

修正后可直接运行的代码

假设你表里标识观测先后顺序的字段叫obs_id(就是你示例最左列1-20的序号,替换成你表里实际的自增ID/时间戳字段即可),不需要建多个中间表,单条SQL就能出最终结果:

CREATE TABLE FINAL AS
SELECT *,
    AVG(var_1) OVER (PARTITION BY id ORDER BY obs_id ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS var_1_lag_2,
    AVG(var_1) OVER (PARTITION BY id ORDER BY obs_id ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS var_1_lag_3,
    AVG(var_1) OVER (PARTITION BY id ORDER BY obs_id ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS var_1_lag_4,
    AVG(var_1) OVER (PARTITION BY id) AS var_1_lag_all
FROM my_data;

补充说明:如果你表里确实没有能标识观测先后顺序的字段,数据库本身无法判定哪条属于「最近」的记录,滚动均值的计算结果是随机不稳定的,没有实际业务意义。
如果硬要说你原来的三步写法哪里能得到正确值:假设你把窗口的ORDER BY字段换成正确的顺序字段,那最后左连得到的var_1_lag_all数值是对的,但属于冗余实现,效率比直接用窗口函数低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:15:36