如何避免两次INNER JOIN返回重复值,实现按供应商分组统计采购订单量
按物料号+供应商统计采购订单总数量的正确SQL方案
问题核心
要实现:同物料号的采购订单,按供应商拆分统计订购数量总和,但当前遇到两个问题:
- 两次INNER JOIN查询返回重复值,导致统计结果偏大
- 子查询触发“子查询返回多个值”的错误
问题根源
- JOIN出重复值:因为关联的表存在一对多关系(比如一个采购单对应多条物料明细),JOIN后主表数据被重复展开,统计时数量被多次计算。
- 子查询报错:子查询没做聚合处理,返回了多条结果,而外部查询用了单值匹配逻辑(比如
=),导致冲突。
解决思路
先对包含订购数量的明细数据按stocknumber和vendornumber做预聚合,再关联其他业务表(如果需要补充维度字段),从根源避免JOIN带来的重复展开。
基于常见业务表的SQL实现
假设核心业务表如下(如果你的表结构不同,仅需调整关联字段即可):
purchase_orders:采购订单主表(存储vendornumber、订单ID等)po_items:采购订单明细表(存储stocknumber、qty_ordered、关联订单ID等)- 另外3张业务表(如物料信息表、供应商信息表等,用于补充名称类维度字段)
方案1:最简洁的聚合统计(优先选用)
SELECT pi.stocknumber, po.vendornumber, SUM(pi.qty_ordered) AS total_order_qty -- 如需补充物料、供应商名称,添加以下关联与字段 -- , m.material_name, v.vendor_name FROM po_items pi INNER JOIN purchase_orders po ON pi.po_id = po.po_id -- LEFT JOIN materials m ON pi.stocknumber = m.stocknumber -- LEFT JOIN vendors v ON po.vendornumber = v.vendornumber GROUP BY pi.stocknumber, po.vendornumber -- 若使用SQL Server等要求严格分组的数据库,GROUP BY需包含所有非聚合字段 -- GROUP BY pi.stocknumber, po.vendornumber, m.material_name, v.vendor_name ORDER BY pi.stocknumber, po.vendornumber;
方案2:用子查询避免JOIN重复(适配特殊场景)
如果必须用子查询,确保子查询返回单值(通过聚合函数实现):
SELECT t.stocknumber, t.vendornumber, SUM(t.qty_ordered) AS total_order_qty FROM ( -- 子查询先关联订单与明细,确保每条记录是唯一的物料-订单行 SELECT pi.stocknumber, po.vendornumber, pi.qty_ordered FROM po_items pi INNER JOIN purchase_orders po ON pi.po_id = po.po_id -- 关联其他表时需注意,不要引入一对多的重复数据 ) t GROUP BY t.stocknumber, t.vendornumber ORDER BY t.stocknumber, t.vendornumber;
避坑提示
- 绝对不要先JOIN所有表再聚合,一定要先聚合明细,再关联维度表,否则必然出现重复统计。
- 关联其他表时优先用
LEFT JOIN,避免INNER JOIN过滤掉有订单但维度表无记录的数据。 - 子查询里必须用聚合函数(如
SUM())确保返回单值,否则会触发“返回多个值”的错误。
内容的提问来源于stack exchange,提问作者Ace
相关产品推荐
相关产品推荐

