0

我正在尝试在以下脚本中使用 SQL Merge 合并两个表:

 BEGIN TRAN;
DECLARE @T TABLE(Id BigInt);
MERGE Target AS T
USING Source AS S
ON (T.ObjectName = S.ObjectName) 
WHEN NOT MATCHED BY TARGET 
     THEN INSERT(ObjectName,Value,[TimeStamp],Quality) VALUES(S.ObjectName, S.Value,S.[TimeStamp],S.Quality)
WHEN MATCHED 
    THEN UPDATE SET 
    T.Value = S.Value,
    T.Quality=S.Quality

OUTPUT S.Id INTO @T;
DELETE Source
WHERE Id in (SELECT Id
                     FROM @T);
if @@Error > 0
Rollback
else
COMMIT Tran
GO 

我要做的是从 to 插入新记录"Target""Source"记录"Matched"将在"Source"表中更新。我面临的问题是,有时,源表有两个相同的"Not Matched Rows". 根据脚本逻辑和我的要求,它应该插入第一个"Not Matched",然后第二个“不匹配”需要被视为更新,而不是插入,因为它现在是"Matched"一行,因为我们已经插入了第一个记录。

似乎我的合并作为一个批量脚本工作,当脚本到达第二个相同的行时,第一个插入不会被注意到。这是“SQL Merge”的工作方式还是我的脚本?

谢谢

4

1 回答 1

4

假设具有较晚时间戳的行应该“获胜”,为什么不消除重复作为SOURCE查询的一部分:

;With Selection as (
    select ObjectName,Value,Quality,
      ROW_NUMBER() OVER (PARTITION BY ObjectName ORDER BY Timestamp desc) as rn,
      MIN(Timestamp) OVER (PARTITION BY ObjectName) as Timestamp
    from
      Source
)
MERGE Target AS T
USING (select * from Selection where rn=1) AS S
--The rest is unaltered
...

这并不是什么不寻常的事情MERGE——所有 DML 语句都“好像”同时处理所有行。

于 2013-07-18T06:59:02.627 回答