首页/数据/数仓建模速查/窗口指标的 SQL 实现要点
指标体系63 条

窗口指标的 SQL 实现要点

窗口指标(近 N 日、滚动累计)在明细层用开窗或区间过滤实现:注意「按天输出滚动值」与「只算当天窗口」的差异,前者结果列随统计日变化。

数仓建模速查数据更新于 2026-10-13

两种实现思路

窗口指标(近 N 日、滚动累计)在明细层有两种实现:按每个统计日重新过滤区间重算,结果列随统计日变化,逻辑直观但反复扫描历史分区;用开窗函数在连续日期序列上累积,一次扫描完成但依赖日期序列完整。两者在大数据量下成本差异明显,实践中常用增量算法或交给 OLAP 引擎承接查询,同时必须写清窗口是否包含统计当日,否则与去年同期比较时会差一天。

基本信息

区间过滤逐统计日重算窗口,逻辑直观
开窗累积连续序列上滚动,适合日粒度
性能大表优先预聚合或由 OLAP 承接
口径要点窗口是否包含统计当日
边界月初、年初等不完整窗口需标注

典型使用场景

  • 近 7 日、近 30 日活跃与支付金额这类滚动指标
  • 月初至今、年初至今等累计指标,窗口随日期增长
  • 滚动均值与滚动同比,用于平滑短期波动
  • 大表场景用预聚合表承载滚动窗口,避免每次扫明细
  • 不完整窗口(月初前六天)在报表中标注,避免被误读

区间重算与开窗

区间重算与开窗
-- 输出每天的近 7 日支付金额(每个统计日重算区间)
SELECT a.dt,
       (SELECT sum(pay_amt) FROM fact_pay b
        WHERE b.dt BETWEEN date_sub(a.dt, 6) AND a.dt) AS pay_amt_7d
FROM dim_date a
WHERE a.dt BETWEEN '2026-10-01' AND '2026-10-11';

-- 日期序列连续时用窗口函数一次算完
SELECT dt,
       sum(pay_amt) OVER (ORDER BY dt
         ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS pay_amt_7d
FROM dws_pay_day;

实现对照

实现方式适用条件代价
区间过滤重算查询频率低、数据量小重复扫描历史分区
开窗累积日粒度连续、无缺失日期依赖日期序列完整
预聚合表滚动窗口被反复查询需要维护汇总与回补
OLAP 引擎承接交互式查询、时延敏感依赖引擎能力与资源配置
窗口定义要一次写清:是否含统计当日、按自然日还是业务日、缺失日期是否补零。这三条不明确,两个团队算出的滚动值必然不同。
日期序列必须连续:开窗累积遇到缺失日期会直接跳过,结果看起来正常,但窗口实际覆盖天数不足,需要先用日期维补齐。

易错点

  • 含当天与不含当天两种实现混用,跨报表相差一天
  • 逐日重算不做预聚合,查询超时后只能人工降级
  • 日期序列不连续,开窗累积的实际窗口天数不足
  • 不完整窗口不标注,月初的累计指标被当成完整周期解读

数据来源与参考

  • SQL 窗口函数实践;指标平台实现笔记
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌