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

SQL多表Join时如何排除重复行 正确匹配工厂与物料提前期

问题根因

你当前的关联逻辑没有区分专属提前期和通用提前期的优先级:直接关联plant为空的通用规则行时,会把已经配置了专属提前期的工厂也匹配到通用规则,最终生成重复记录、提前期取值错误。

正确实现方案

实现核心是保证规则优先级:指定工厂的专属提前期优先级 > 空plant的通用提前期,已经匹配到专属规则的工厂不再匹配通用规则。

通用SQL写法(兼容所有SQL方言)

用CTE拆分两类规则,分别关联后合并结果,兼容性最好:

WITH specific_rule AS (
    -- 提取所有配置了专属提前期的记录
    SELECT porg, matnr, plant, lead_time
    FROM TableA
    WHERE plant <> ''
),
general_rule AS (
    -- 提取所有采购组织+物料维度的通用提前期记录
    SELECT porg, matnr, lead_time
    FROM TableA
    WHERE plant = '' OR plant IS NULL
)
-- 第一部分:匹配专属提前期的工厂
SELECT 
    b.porg,
    sr.matnr,
    b.plant,
    sr.lead_time
FROM TableB b
INNER JOIN specific_rule sr
    ON b.porg = sr.porg AND b.plant = sr.plant

UNION ALL

-- 第二部分:匹配无专属规则、使用通用提前期的工厂
SELECT
    b.porg,
    gr.matnr,
    b.plant,
    gr.lead_time
FROM TableB b
INNER JOIN general_rule gr
    ON b.porg = gr.porg
-- 排除已经配置了专属提前期的工厂,避免重复
LEFT JOIN specific_rule sr
    ON b.porg = sr.porg 
    AND b.plant = sr.plant 
    AND gr.matnr = sr.matnr
WHERE sr.porg IS NULL
ORDER BY porg, matnr, plant;

执行后输出结果和你预期完全一致。

简洁写法(支持QUALIFY语法的SQL环境)

如果使用Snowflake、BigQuery、PostgreSQL 13+等支持QUALIFY窗口函数语法的环境,可以用更短的代码实现相同逻辑:

SELECT
    b.porg,
    a.matnr,
    b.plant,
    a.lead_time
FROM TableB b
LEFT JOIN TableA a
    ON b.porg = a.porg
    AND (a.plant = b.plant OR a.plant = '' OR a.plant IS NULL)
-- 同维度下优先取专属提前期的记录
QUALIFY ROW_NUMBER() OVER (
    PARTITION BY b.porg, b.plant, a.matnr
    ORDER BY CASE WHEN a.plant = b.plant THEN 0 ELSE 1 END
) = 1
ORDER BY porg, matnr, plant;
逻辑说明
  • 专属规则永远优先匹配:只要TableA中给对应porg+matnr+plant配置了明确的提前期,就不会再取通用值
  • 通用规则仅对没有配置专属提前期的工厂生效,不会产生重复记录
  • 完全匹配业务规则:空plant的提前期自动覆盖该采购组织下所有未单独配置的合法工厂

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:33:39