PostgreSQL按月份截断日期计算累计求和SQL查询求助
实现PostgreSQL按月按分类的累计求和
你的原查询已经正确计算了每个分类的月度成本总和,要实现累计递增的效果,只需在原查询基础上用PostgreSQL的窗口函数计算累计值即可,无需复杂嵌套。
修改后的查询如下:
WITH monthly_sums AS ( SELECT date_trunc('month', "public"."stock_transaction"."created_at") AS "month", "Category"."name" AS "Category - name", sum("public"."stock_transaction"."cost") AS "monthly_sum" FROM "public"."stock_transaction" LEFT JOIN "public"."product" "Product" ON "public"."stock_transaction"."product_id" = "Product"."id" LEFT JOIN "public"."category" "Category" ON "Product"."category_id" = "Category"."id" WHERE ( "public"."stock_transaction"."owner_id" = {{organization.id}}::uuid AND {{createdAt}} AND "Product"."recipe" = FALSE ) GROUP BY "month", "Category"."name" ) SELECT "month" AS "created_at", "Category - name", "monthly_sum" AS "monthly_cost", SUM("monthly_sum") OVER ( PARTITION BY "Category - name" ORDER BY "month" ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS "cumulative_cost" FROM monthly_sums ORDER BY "month" ASC, "Category - name" ASC;
关键说明:
- CTE 临时表:
monthly_sums复用了你原查询的逻辑,先算出每个分类每个月的成本小计,调整别名让逻辑更清晰。 - 窗口函数核心:
SUM("monthly_sum") OVER (...)实现累计:PARTITION BY "Category - name":确保累计按单个分类独立计算,不会跨分类混淆。ORDER BY "month" ASC:指定按时间顺序从早到晚累加。ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:明确从当前分类的第一个月开始,累加到当前月份(PostgreSQL中如果ORDER BY是时间列,默认就是这个范围,写出来更直观)。
- 兼容Metabase变量:原查询中的
{{organization.id}}和{{createdAt}}变量完全保留,不影响Metabase的参数交互。
效果示例:
若某分类1月成本100,2月200,3月150,查询结果会显示:
- 1月:月度成本100,累计成本100
- 2月:月度成本200,累计成本300
- 3月:月度成本150,累计成本450
直接用cumulative_cost作为图表数值字段,就能生成递增柱状图。
内容的提问来源于stack exchange,提问作者Sébastien
相关产品推荐
相关产品推荐

