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

如何基于时间范围实现分组窗口聚合?——计算客户30天内产品购买总量

解决方案:计算客户30天内累计购买量

嘿,我懂你碰到的这个棘手问题了——你之前用PARTITION BY CustomerID, Dat-30的思路确实不对,因为这种分区是把每个日期减去30天后的值作为分组依据,根本没法覆盖连续的30天时间范围。咱们得用窗口函数里的范围窗口框架来实现这个动态累计需求,核心思路是:针对每个客户,计算当前行日期及往前30天内所有记录的Amount总和。

下面根据不同数据库类型给出具体的SQL写法,你可以根据自己使用的数据库选择对应的版本:

1. PostgreSQL

PostgreSQL原生支持在窗口框架中使用日期区间,写法最直观:

SELECT
  CustomerID,
  Amount,
  Dat,
  SUM(Amount) OVER (
    PARTITION BY CustomerID  -- 按客户分组
    ORDER BY Dat::DATE       -- 按购买日期排序
    -- 定义窗口范围:当前日期往前30天到当前行
    RANGE BETWEEN INTERVAL '30 days' PRECEDING AND CURRENT ROW
  ) AS ProductsIn30Days
FROM your_table_name;

这里Dat::DATE是把Dat字段转换成标准日期类型,确保日期排序和区间计算的准确性。

2. MySQL(8.0+版本)

MySQL的窗口函数对日期类型的RANGE支持需要转成数值型,我们可以用TO_DAYS()把日期转换成自公元0年以来的天数,再指定30天的范围:

SELECT
  CustomerID,
  Amount,
  Dat,
  SUM(Amount) OVER (
    PARTITION BY CustomerID
    ORDER BY TO_DAYS(Dat)
    -- 往前30天对应的天数差值是30
    RANGE BETWEEN 30 PRECEDING AND CURRENT ROW
  ) AS ProductsIn30Days
FROM your_table_name;

3. SQL Server

SQL Server需要用DATEADD来计算30天前的日期,同时确保日期格式正确:

SELECT
  CustomerID,
  Amount,
  Dat,
  SUM(Amount) OVER (
    PARTITION BY CustomerID
    ORDER BY CONVERT(DATE, Dat)
    -- 动态计算当前日期往前30天的边界
    RANGE BETWEEN DATEADD(DAY, -30, CONVERT(DATE, Dat)) PRECEDING AND CURRENT ROW
  ) AS ProductsIn30Days
FROM your_table_name;

验证示例数据

拿你给出的示例来看,比如CustomerID=1、Dat=25.3.2020的记录:

  • 该客户在24.3.2020的两条记录(Amount=2和3)都在25.3.2020往前30天范围内,加上当前的2,总和正好是7,和你预期的结果一致。

如果你的数据库是其他类型(比如Oracle),可以告诉我,我再调整对应的写法~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:07:39