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

SQL Server中源表含重复主键值时的MERGE语句改写求助

解决MERGE语句因源表重复主键报错的问题

这问题我刚学SQL的时候也踩过坑!核心原因很明确:你的源表SCM_Top_Up_Rolling里同一个String主键对应了多条记录(比如示例里的B418496220有两条),当MERGE匹配到目标表的同一条记录时,数据库不知道该用源表的哪条来更新,所以抛出了“尝试更新或删除多条记录”的错误。

你的需求是取每个String的最新记录(Date_Added最大)来做更新/插入,所以解决思路是先对源表做预处理,只保留每个String的最新数据,再用这个预处理后的数据集做MERGE。

方案1:用窗口函数筛选最新记录(推荐)

用ROW_NUMBER()窗口函数给每个String分组内的记录按Date_Added降序编号,只取编号为1的最新记录:

MERGE SCM_Top_Up_Operational O 
USING (
    SELECT *
    FROM (
        SELECT 
            String, 
            Date_Added, 
            Real_Exfact, 
            Article_ID, 
            Excess_Top_Up, 
            Plant,
            -- 给每个String的记录按Date_Added倒序编号,最新的行号为1
            ROW_NUMBER() OVER (PARTITION BY String ORDER BY Date_Added DESC) AS rn
        FROM SCM_Top_Up_Rolling
    ) t
    WHERE t.rn = 1 -- 只保留每个String的最新记录
) R 
ON (O.String = R.String)
WHEN MATCHED THEN 
UPDATE SET 
    O.Date_Added = R.Date_Added, 
    O.Real_Exfact = R.Real_Exfact, 
    O.Excess_Top_Up = R.Excess_Top_Up 
WHEN NOT MATCHED BY TARGET THEN 
INSERT ( String, Date_Added, Real_Exfact, Article_ID, Excess_Top_Up, Plant) 
VALUES (R.String, R.Date_Added, R.Real_Exfact, R.Article_ID, R.Excess_Top_Up, R.Plant);

方案2:用自增RECORD_ID筛选最新记录

因为你的源表RECORD_ID是自增主键,最新的记录必然对应最大的RECORD_ID,也可以用这个逻辑来筛选:

MERGE SCM_Top_Up_Operational O 
USING (
    SELECT R.*
    FROM SCM_Top_Up_Rolling R
    INNER JOIN (
        -- 先找出每个String对应的最大RECORD_ID
        SELECT String, MAX(RECORD_ID) AS max_record_id
        FROM SCM_Top_Up_Rolling
        GROUP BY String
    ) t ON R.String = t.String AND R.RECORD_ID = t.max_record_id
) R 
ON (O.String = R.String)
WHEN MATCHED THEN 
UPDATE SET 
    O.Date_Added = R.Date_Added, 
    O.Real_Exfact = R.Real_Exfact, 
    O.Excess_Top_Up = R.Excess_Top_Up 
WHEN NOT MATCHED BY TARGET THEN 
INSERT ( String, Date_Added, Real_Exfact, Article_ID, Excess_Top_Up, Plant) 
VALUES (R.String, R.Date_Added, R.Real_Exfact, R.Article_ID, R.Excess_Top_Up, R.Plant);

执行后效果

按你的示例数据,执行后目标表会变成:

  • B418496220会被更新为源表中Date_Added=2019-03-28的最新记录
  • 目标表不存在的B111116220会被完整插入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:54:20