PostgreSQL:如何按日期对窗口函数生成列进行求和?
解决方案:计算每日各区域平均收入的总和(total_avg)
嘿,这个需求其实很容易实现,你只需要在现有生成avg_rev的查询基础上,再加一个窗口求和函数就能得到total_avg。下面是两种清晰的实现方式:
方式一:子查询嵌套
直接在你原有的查询外层,添加一个按日期分组的窗口求和:
SELECT date, sales_region, rev, avg_rev, -- 按日期分组,求和所有区域的avg_rev SUM(avg_rev) OVER (PARTITION BY date) AS total_avg FROM ( -- 这里是你原来计算7天平均收入的逻辑 SELECT date, sales_region, rev, -- 注意:添加ORDER BY date保证窗口行范围的正确性 AVG(rev) OVER ( PARTITION BY sales_region ORDER BY date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW ) AS avg_rev FROM your_sales_table ) AS avg_rev_subquery;
方式二:CTE(公共表达式)
如果你的数据库支持CTE(比如PostgreSQL、MySQL 8+、SQL Server等),用这种写法会让代码更易读:
WITH avg_rev_cte AS ( -- 先计算出每个区域的7天平均收入avg_rev SELECT date, sales_region, rev, AVG(rev) OVER ( PARTITION BY sales_region ORDER BY date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW ) AS avg_rev FROM your_sales_table ) -- 再基于CTE计算每日的total_avg SELECT date, sales_region, rev, avg_rev, SUM(avg_rev) OVER (PARTITION BY date) AS total_avg FROM avg_rev_cte;
关键说明:
SUM(avg_rev) OVER (PARTITION BY date)这个窗口函数会把同一日期下所有销售区域的avg_rev值相加,然后将这个总和赋值给该日期的每一行,完全符合你需要的total_avg效果。- 我在原窗口函数里加了
ORDER BY date,这很重要——因为ROWS BETWEEN 7 PRECEDING AND CURRENT ROW依赖于行的顺序,确保是按日期的先后顺序计算过去7天的平均值,避免结果出现混乱。
用你的示例数据测试的话,01-23-18的total_avg就是187463 + 90245 + 270974 = 548682,01-24-18的total_avg是189245 + 91621 + 269874 = 550740,和你期望的结果完全一致。
内容的提问来源于stack exchange,提问作者Javier Fernandez
相关产品推荐
相关产品推荐

