PostgreSQL:按B/C/D/E/F分组,对去重A列对应G列求和
PostgreSQL 按指定列分组求和并解决A列重复导致的计算错误
需要按B、C、D、E、F五列分组计算G列的求和值,但因A列存在重复记录,导致直接分组求和结果错误。现有两种尝试均未得到正确结果:
- 初始查询未处理A列重复,返回5条记录但求和值因重复累加错误:
select B,C, D, E, F, sum(G) as Totals from Table where B= '101' and C = '2024-05-06' group by B,C, D, E, F
- 添加A列分组后,返回88条记录,分组粒度不符合需求,求和仍错误:
select distinct A,B,C, D, E, F, sum(G) as Totals from Table where B= 'value' and date = '2024-05-06' group by B,C, D, E, F,A
期望结果:按B、C、D、E、F分组得到5条记录,求和值为去重A列后的对应值。
方法一:使用PostgreSQL特有DISTINCT ON语法去重
先通过子查询去除A列的重复记录(确保每个A只保留一条对应的B/C/D/E/F/G组合),再按目标列分组求和:
SELECT B, C, D, E, F, SUM(G) AS Totals FROM ( SELECT DISTINCT ON (A) A, B, C, D, E, F, G FROM "Table" WHERE B = '101' AND C = '2024-05-06' -- 若需指定保留A组内的某条记录,可添加ORDER BY子句,例如 ORDER BY A, G DESC ) AS deduplicated_data GROUP BY B, C, D, E, F;
方法二:使用窗口函数ROW_NUMBER()通用去重
如果需要兼容其他数据库,可使用窗口函数标记每个A组的唯一记录,再过滤后聚合:
SELECT B, C, D, E, F, SUM(G) AS Totals FROM ( SELECT A, B, C, D, E, F, G, ROW_NUMBER() OVER (PARTITION BY A ORDER BY A) AS row_num FROM "Table" WHERE B = '101' AND C = '2024-05-06' -- ORDER BY可根据需求调整,比如按G的大小排序来决定保留哪条记录 ) AS deduplicated_data WHERE row_num = 1 GROUP BY B, C, D, E, F;
说明
两种方法的核心都是先对A列去重,确保每个A对应的B/C/D/E/F/G只参与一次求和,再按目标列分组计算,这样就能得到5条符合要求的记录,且求和值正确。若同一A对应多条不同的G值,需根据业务规则调整子查询中的ORDER BY子句,决定保留哪一条记录。
内容的提问来源于stack exchange,提问作者Subhashree Nayak
相关产品推荐
相关产品推荐

