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

SQL实现按月份累计求和:替代低效Union查询方案

问题描述

我有一张包含pieces(数量)和Date(日期)两列的数据表,示例数据如下:

pieces          Date

100             2022-01-01
200             2022-02-01
300             2022-03-01

以此类推。我需要实现按月份累计求和,期望得到如下结果:

january    - 100 pieces
february   - 300 pieces
march      - 600 pieces

目前我尝试用多个SELECT语句分别计算截至各月末的总和,再通过UNION合并结果,但这种方式效率很低,代码如下:

select
  sum(pieces)
  , 'january' as month
from
  table
where
  date <= '2022-01-31'
union
select
  sum(pieces)
  , 'february' as month
from
  table
where
  date <= '2022-02-28'
union
select
  sum(pieces)
  , 'march' as month
from
  table
where
  date <= '2022-03-31'
高效解决方案

可以利用窗口函数实现一次扫描表完成累计求和,效率远高于多次UNION的方式,以下是适配不同数据库的实现方案:

MySQL 版本

SELECT
  LOWER(MONTHNAME(date)) AS month,
  CONCAT(SUM(pieces) OVER (ORDER BY MONTH(date)), ' pieces') AS result
FROM
  your_table
GROUP BY
  MONTH(date), MONTHNAME(date)
ORDER BY
  MONTH(date);

PostgreSQL 版本

SELECT
  LOWER(TO_CHAR(date, 'FMMonth')) AS month,
  CONCAT(SUM(pieces) OVER (ORDER BY EXTRACT(MONTH FROM date)), ' pieces') AS result
FROM
  your_table
GROUP BY
  EXTRACT(MONTH FROM date), TO_CHAR(date, 'FMMonth')
ORDER BY
  EXTRACT(MONTH FROM date);

SQL Server 版本

SELECT
  LOWER(DATENAME(MONTH, date)) AS month,
  CONCAT(SUM(pieces) OVER (ORDER BY MONTH(date)), ' pieces') AS result
FROM
  your_table
GROUP BY
  MONTH(date), DATENAME(MONTH, date)
ORDER BY
  MONTH(date);

核心逻辑说明

  1. 用数据库内置函数提取月份的英文名称,并转为小写以匹配期望格式
  2. SUM(pieces) OVER (ORDER BY 月份序号) 是累计求和的核心:窗口函数会按月份顺序,自动累加当前及之前所有月份的pieces总和
  3. 通过GROUP BY确保每个月份只返回一条记录,最后按月份序号排序保证结果顺序正确

优势

  • 仅需扫描数据表一次,避免了多次SELECT+UNION的重复扫描,数据量越大效率提升越明显
  • 无需手动指定每个月末日期,自动适配不同月份的天数(如2月的28/29日)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:55:19