如何使用SUM() OVER (PARTITION BY)?按日/月分组求和实现
场景说明
假设11月1日至3日售卖A、B两类商品,需统计每日销售总量与总金额。现有表格数据如下:
Date Type Quantity Amount Sum_Quantity Sum_Amount 01-11 A 2 100 5 300 01-11 B 3 200 5 300 02-11 A 1 700 3 950 02-11 B 2 250 3 950 03-11 A 2 600 7 800 03-11 B 5 200 7 800
问题1:如何编写查询语句得到最后两列(Sum_Quantity、Sum_Amount)?
直接用窗口函数按日期分区求和即可,无需额外分组关联。以下是适用于MySQL 8+、PostgreSQL、SQL Server等主流数据库的通用写法:
SELECT Date, Type, Quantity, Amount, SUM(Quantity) OVER (PARTITION BY Date) AS Sum_Quantity, SUM(Amount) OVER (PARTITION BY Date) AS Sum_Amount FROM your_table_name;
说明:
PARTITION BY Date指定按日期维度分组计算聚合值- 窗口函数会为每个日期下的所有行,返回该日期对应的总销量和总金额,和示例中最后两列的逻辑完全匹配
问题2:若需按月份分区统计,该如何编写查询语句?
核心是先从日期中提取月份维度,再按月份做聚合或窗口计算,不同数据库提取月份的函数略有差异,以下分两种场景给出写法:
场景1:单独统计每月总销量与总金额(单行展示月度数据)
SELECT -- 不同数据库提取月份的函数不同,按需选择 DATE_TRUNC('month', Date) AS Month, -- PostgreSQL/Redshift -- MONTH(Date) AS Month, -- MySQL/SQL Server -- TO_CHAR(Date, 'YYYY-MM') AS Month, -- Oracle SUM(Quantity) AS Total_Monthly_Quantity, SUM(Amount) AS Total_Monthly_Amount FROM your_table_name GROUP BY -- 与上方提取月份的表达式保持一致 DATE_TRUNC('month', Date);
场景2:保留原始行,同时添加当月总销量与总金额列
SELECT Date, Type, Quantity, Amount, SUM(Quantity) OVER (PARTITION BY DATE_TRUNC('month', Date)) AS Monthly_Sum_Quantity, SUM(Amount) OVER (PARTITION BY DATE_TRUNC('month', Date)) AS Monthly_Sum_Amount FROM your_table_name;
注意:
如果你的Date字段是字符串格式(如示例中的01-11),需要先转换为日期类型再提取月份,比如MySQL中可以用STR_TO_DATE(Date, '%d-%m')转换后,再用MONTH()提取月份。
内容的提问来源于stack exchange,提问作者Madi M
相关产品推荐
相关产品推荐

