You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免两次INNER JOIN返回重复值,实现按供应商分组统计采购订单量

按物料号+供应商统计采购订单总数量的正确SQL方案

问题核心

要实现:同物料号的采购订单,按供应商拆分统计订购数量总和,但当前遇到两个问题:

  1. 两次INNER JOIN查询返回重复值,导致统计结果偏大
  2. 子查询触发“子查询返回多个值”的错误

问题根源

  • 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;

避坑提示

  1. 绝对不要先JOIN所有表再聚合,一定要先聚合明细,再关联维度表,否则必然出现重复统计。
  2. 关联其他表时优先用LEFT JOIN,避免INNER JOIN过滤掉有订单但维度表无记录的数据。
  3. 子查询里必须用聚合函数(如SUM())确保返回单值,否则会触发“返回多个值”的错误。

内容的提问来源于stack exchange,提问作者Ace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:20:48