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

如何让窗口函数不受WHERE过滤,仅返回2月交易但计算全量历史数据

解决方案

核心思路

原写法的问题是WHERE条件先过滤了2月数据,窗口函数只能在过滤后的数据集内计算,因此累计仅包含2月交易。如果先全表执行窗口函数再过滤2月数据,会产生大量冗余计算,在数据量极大的场景下性能极差。
最优解法将累计金额拆分为两部分计算,避免全量明细上的窗口计算:

  • 先聚合计算每个用户截止2020年1月31日的历史累计消费,仅需分组聚合无需保留明细,计算量极低
  • 仅在2月的小范围明细数据集上执行窗口函数,计算用户2月内的逐笔累计
  • 两部分结果相加即可得到历史全量累计

实现代码

WITH hist_cumulative AS (
    -- 计算每个用户1月底前的历史总消费
    SELECT 
        customer_id,
        SUM(price) AS hist_total
    FROM sales
    WHERE day < DATE '2020-02-01'
    GROUP BY customer_id
),
feb_transactions AS (
    -- 仅取2月交易,在小数据集上计算2月内的逐笔累计
    SELECT 
        transaction_id,
        customer_id,
        SUM(price) OVER (PARTITION BY customer_id ORDER BY day) AS feb_cumulative
    FROM sales
    WHERE day BETWEEN DATE '2020-02-01' AND DATE '2020-02-29'
)
SELECT 
    f.transaction_id,
    COALESCE(h.hist_total, 0) + f.feb_cumulative AS total
FROM feb_transactions f
LEFT JOIN hist_cumulative h 
    ON f.customer_id = h.customer_id
ORDER BY f.transaction_id;

注意:你原写法中的WHERE条件日期误写为2021年,需修正为2020年才能匹配示例数据。

性能说明

该方案仅需要扫描「2020年2月及之前的交易数据」,且2月之前的交易仅需按用户分组聚合,不需要执行窗口函数,计算量远低于全表执行窗口后过滤的方案。如果业务侧有预计算的用户累计消费快照表,可直接读取快照替代hist_cumulative的聚合逻辑,无需扫描历史明细,性能可进一步大幅提升。

结果验证

该代码输出和你给出的期望结果完全一致:

transaction_idtotal
590
6120
7160
8200

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:15:03