如何避免采购订单与发票表关联查询时产生重复行?
解决VBRP与EKPO关联时同物料多记录的笛卡尔积问题
当前关联逻辑仅通过Po_Num和Material匹配,导致同一采购订单下同一物料的多条开票记录(vbrp)与多条PO行记录(ekpo)产生笛卡尔积,出现错误的数量组合。以物料B为例,vbrp有两条记录(7、11),ekpo也有两条记录(7、11),关联后生成4条结果,仅7-7、11-11是符合业务的正确匹配。
解决方案:通过窗口函数添加行号实现精准匹配
由于无法修改表结构,我们可以利用窗口函数为同PO、同物料的记录生成唯一行号,通过行号+PO+物料的组合条件关联,避免全量匹配。
方案1:按数量排序匹配(适用于数量一一对应场景)
通过ROW_NUMBER()窗口函数,给每个Po_Num+Material分组内的记录按数量排序生成行号,确保相同数量的记录一一对应:
WITH vbrp_ranked AS ( SELECT Billing_doc, Material, Billed_Qty, Po_Num, ROW_NUMBER() OVER (PARTITION BY Po_Num, Material ORDER BY Billed_Qty) AS rn FROM vbrp WHERE Billing_doc = 122 ), ekpo_ranked AS ( SELECT Po_Num, Material, PO_qty, ROW_NUMBER() OVER (PARTITION BY Po_Num, Material ORDER BY PO_qty) AS rn FROM ekpo ) SELECT v.Billing_doc, v.Material, v.Billed_Qty, e.PO_qty FROM vbrp_ranked v JOIN ekpo_ranked e ON v.Po_Num = e.Po_Num AND v.Material = e.Material AND v.rn = e.rn;
方案2:按业务行号排序匹配(适用于数量可能重复但行号顺序对应的场景)
如果业务中开票行(Bill_doc_line)与PO行(PO_line)是按顺序对应的,可按行号排序生成行号关联:
WITH vbrp_ranked AS ( SELECT Billing_doc, Material, Billed_Qty, Po_Num, ROW_NUMBER() OVER (PARTITION BY Po_Num, Material ORDER BY Bill_doc_line) AS rn FROM vbrp WHERE Billing_doc = 122 ), ekpo_ranked AS ( SELECT Po_Num, Material, PO_qty, ROW_NUMBER() OVER (PARTITION BY Po_Num, Material ORDER BY PO_line) AS rn FROM ekpo ) SELECT v.Billing_doc, v.Material, v.Billed_Qty, e.PO_qty FROM vbrp_ranked v JOIN ekpo_ranked e ON v.Po_Num = e.Po_Num AND v.Material = e.Material AND v.rn = e.rn;
效果验证
以上两种方案执行后,物料B仅会返回7-7、11-11两条正确记录,其他物料的关联结果也符合业务预期。
内容的提问来源于stack exchange,提问作者Zqm
相关产品推荐
相关产品推荐

