SQL按itemCode分组多列求和并保留fac列明细值实现方法
按itemCode分组保留明细同时计算分组和的实现方案
问题场景
现有一个返回40余列的大型复杂查询,当前结果样例如下:
| itemCode | itemName | customerCode | customerName | fac1 | fac2 | sum(fac2) | fac3 | sum(fac3) |
|---|---|---|---|---|---|---|---|---|
| 001 | ABCD | 0023 | Dummy 1 | 0.25 | 0.25 | 0.75 | 0.1 | 0.5 |
| 001 | ABCD | 0024 | Dummy 2 | 0.25 | 0.25 | 0.75 | 0.2 | 0.5 |
| 001 | ABCD | 0025 | Dummy 3 | 0.50 | 0.25 | 0.75 | 0.2 | 0.5 |
| 002 | EFGH | 0023 | Dummy 1 | 0.20 | 0.52 | 0.52 | 0.1 | 0.1 |
| 003 | MNOP | 0023 | Dummy 1 | 0.50 | 0.75 | 1.25 | 0.3 | 0.7 |
| 003 | MNOP | 0024 | Dummy 2 | 0.20 | 0.50 | 1.25 | 0.4 | 0.7 |
需求要求:
- 结果必须保留所有fac系列列的单行明细值,不能折叠明细行
- 求和计算仅按itemCode维度分组,不需要按全量返回字段、也不需要按customerCode维度分组
- 同一个itemCode对应的分组求和结果,允许在组内每一行明细上重复展示
实现方法
直接使用窗口函数即可实现需求,不需要改动原有复杂查询的逻辑,也不需要做GROUP BY折叠行:只需要在聚合函数后追加OVER (PARTITION BY itemCode)子句,就能指定按itemCode分区计算聚合值,同分区下所有行都会返回相同的聚合结果,完全匹配要求。
参考代码如下,你可以用CTE包裹原有40余列的复杂查询逻辑,避免重复编写代码:
WITH base_result AS ( -- 此处原样粘贴你已有的复杂查询逻辑,不需要做任何修改 SELECT itemCode, itemName, customerCode, customerName, fac1, fac2, fac3 -- 其余原有字段全部保留在此处 FROM 你原有的多表关联/过滤逻辑 ) SELECT *, SUM(fac2) OVER (PARTITION BY itemCode) AS `sum(fac2)`, SUM(fac3) OVER (PARTITION BY itemCode) AS `sum(fac3)` -- 其余需要按itemCode求和的fac字段,按上述格式追加即可 FROM base_result;
说明
- 该语法兼容所有主流SQL引擎,包括MySQL 8.0+、PostgreSQL、SQL Server、Hive、Spark SQL、ClickHouse等,无额外适配成本
- 原有查询返回的明细行、字段值完全不会被修改,仅额外追加分组求和列,不会出现分组维度错误、明细丢失的问题
- 如果需要在求和时增加过滤规则(比如排除空值、排除特定状态的行),可以直接在SUM函数内写条件判断,例如
SUM(CASE WHEN fac2 IS NOT NULL THEN fac2 ELSE 0 END) OVER (PARTITION BY itemCode)
内容的提问来源于stack exchange,提问作者Komail Noori
相关产品推荐
相关产品推荐

