You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

求助:按自定义累计季度计算value1季度平均值(over函数异常)

解决特殊定义季度的累计平均值计算问题

嘿,我明白你的问题了——你要的不是常规按季度分段的平均值,而是从当年1月开始累计到对应季度截止月的滚动平均:Q1是1-3月的平均,Q2是1-6月的平均,Q3是1-9月的平均,Q4是全年的平均。之前用OVER函数没得到正确结果,大概率是窗口范围或者分区逻辑没匹配你的特殊季度定义,我来给你一步步解决。

先明确需求对应的逻辑

你的季度本质是累计到特定月份的滚动区间,不是常规的“每3个月为一个独立季度”。先把你的原始数据对应到目标季度节点:

yearmonthvalue1对应季度节点
2016/0133-
2016/0222-
2016/0322Q1(累计1-3月)
2016/0422-
2016/0522-
2016/0625Q2(累计1-6月)
2016/0744-
2016/0844-
2016/0944Q3(累计1-9月)
2016/1066-
2016/1144-
2016/1234Q4(累计全年)

用窗口函数实现累计平均值

我们需要用AVG() OVER()窗口函数,指定从当年第一行到当前行的累计范围,然后筛选出每个季度的截止月份即可。以下是通用SQL写法(支持PostgreSQL、MySQL 8.0+、SQL Server等主流数据库):

WITH monthly_data AS (
    SELECT 
        yearmonth,
        value1,
        -- 提取月份数字,用于判断季度截止点
        CAST(SUBSTRING(yearmonth, 6, 2) AS INT) AS month_num,
        -- 提取年份,确保只计算当年内的累计
        CAST(SUBSTRING(yearmonth, 1, 4) AS INT) AS year_num
    FROM your_table_name -- 替换成你的实际表名
)
SELECT
    year_num AS year,
    CASE month_num
        WHEN 3 THEN 'Q1'
        WHEN 6 THEN 'Q2'
        WHEN 9 THEN 'Q3'
        WHEN 12 THEN 'Q4'
    END AS quarter,
    -- 计算从当年1月到当前月的累计平均值,保留两位小数
    ROUND(AVG(value1) OVER(PARTITION BY year_num ORDER BY month_num ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 2) AS cumulative_avg
FROM monthly_data
-- 只保留每个季度的截止月份数据
WHERE month_num IN (3, 6, 9, 12)
ORDER BY year_num, month_num;

计算结果验证

代入你的数据后,运行结果会是:

yearquartercumulative_avg
2016Q125.67
2016Q224.67
2016Q330.78
2016Q434.92

为什么之前的OVER函数没生效?

大概率是你用了常规的季度分区逻辑(比如PARTITION BY EXTRACT(QUARTER FROM yearmonth)),但常规季度是把1-3、4-6、7-9、10-12分成独立区间,和你要的“从1月开始累计”完全不同。我们这里的核心是累计窗口范围,而非分段分区的窗口。

如果需要保留所有月份的累计平均值(而不只是季度节点),只需要去掉最后的WHERE条件即可,每个月份都会显示从1月到当前月的平均,你可以按需筛选。

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

火山引擎 最新活动