PostgreSQL中GROUP BY结合SUM仍出现重复行问题求助
解决PostgreSQL GROUP BY后未正确聚合的问题
嘿,我来帮你搞定这个问题!你遇到的情况在使用聚合函数时很常见——明明加了SUM和GROUP BY,却还是得到同一维度的多行结果,核心问题出在GROUP BY子句的列选择太宽泛了。
问题根源
你当前的GROUP BY里包含了很多不该作为分组依据的列:
- 那些你用
SUM聚合的字段(比如quantity_pcs、price_per_piece、total_amount等):这些是你要合并的数值,不是分组的维度,把它们放进GROUP BY会导致只要这些字段值不同,就会被分成不同的组 - 时间字段(
date_created、date_updated、date_sync):如果同一分组下存在不同的时间戳,PostgreSQL会把它们拆分成不同的组,自然没法合并成单行
修正后的查询语句
我帮你调整了查询,只保留真正需要分组的维度列,对时间字段使用聚合函数合并,同时简化了WHERE条件:
SELECT tbl_boxes.box_name AS "BOX NAME", tbl_stores.store_name AS "STORE NAME", tbl_sku.sap_name AS "SKU NAME", SUM(tbl_bad_orders_product.quantity_pcs) AS "QUANTITY PER PIECE", -- 注意:如果price_per_piece是单价,SUM不合理,建议用AVG取平均单价 AVG(tbl_bad_orders_product.price_per_piece) AS "PRICE PER PIECE", SUM(tbl_bad_orders_product.quantity_cs) AS "QUANTITY PER CASE", -- 同理,price_per_case如果是单价,用AVG更合理 AVG(tbl_bad_orders_product.price_per_case) AS "PRICE PER CASE", tbl_bad_orders_product.reason AS "REASON", SUM(tbl_bad_orders_product.total_amount) AS "TOTAL AMOUNT", -- 用MIN取最早创建时间,MAX取最晚更新时间,可根据你的需求调整 MIN(tbl_bad_orders_product.date_created) AS "EARLIEST DATE CREATED", MAX(tbl_bad_orders_product.date_updated) AS "LATEST DATE UPDATED", tbl_bad_orders_product.date_sync::date AS "DATE SYNCED" FROM tbl_bad_orders_product INNER JOIN tbl_users ON tbl_bad_orders_product.tbluserid = tbl_users.tbluserid INNER JOIN tbl_boxes ON tbl_bad_orders_product.tblboxid = tbl_boxes.tblboxesid INNER JOIN tbl_stores ON tbl_bad_orders_product.tblstoreid = tbl_stores.tblstoreid INNER JOIN tbl_sku ON tbl_bad_orders_product.tblskuid = tbl_sku.tblskuid WHERE tbl_bad_orders_product.date_sync::date = '2019-02-19' GROUP BY tbl_boxes.box_name, tbl_stores.store_name, tbl_sku.sap_name, tbl_bad_orders_product.reason, tbl_bad_orders_product.date_sync::date ORDER BY tbl_boxes.box_name ASC;
关键调整说明
- 精简GROUP BY列:只保留你想要按其聚合的维度(箱名、门店名、SKU名、原因、同步日期),移除所有要聚合的数值列
- 处理时间字段:对
date_created和date_updated使用MIN/MAX聚合,确保同一分组下的时间值被合并成一个结果;date_sync因为已经在WHERE里限定为同一天,所以可以安全地加入GROUP BY - 单价字段修正:如果
price_per_piece和price_per_case是单价,用SUM会得到错误的结果(把所有单价加起来没有意义),换成AVG取平均单价才合理;如果同一分组下单价完全一致,用MAX或MIN也可以
内容的提问来源于stack exchange,提问作者itTech




