我正在尝试使用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
我要做的是将"Target"
中的新记录插入"Source"
,"Matched"
表中的"Source"
记录将会更新。
我面临的问题是,有时源表有两个相同的"Not Matched Rows"
。根据脚本逻辑和我的要求,它应该插入第一个"Not Matched"
,然后第二个“未匹配”将需要被视为更新,而不是插入,因为它现在是{{1因为我们已经插入了第一条记录。
似乎我的合并正在作为一个批量脚本工作,当脚本到达第二个相同的行时,不会注意到第一个插入。这是“SQL Merge”的工作原理还是形成我的脚本?
由于
答案 0 :(得分:4)
假设具有较晚时间戳的行应该" win",为什么不在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语句都表现为"好像"所有行都是同时处理的。