【问题标题】:Merge: when not matched by source - update rows合并:当源不匹配时 - 更新行
【发布时间】:2017-12-12 02:19:15
【问题描述】:

我正在尝试找出合并函数,我必须更新目标表中存在的行,但这些行与源表中的行不匹配。

那些在源表中不匹配的内容我想在它说的 WHEN NOT MATCHED BY SOURCE 中更新,例如
Update PEOPLE set UPD = null,target.CHANGE = CURRENT_TIMESTAMP where target.ID = source.ID and target.UPD is not null and target.CHANGE is null

这就是目前 MERGE 的样子,我想我需要一些输出来提供不匹配的 ID,以便我可以更新它们,但不确定如何更新。

例如,这是 PEOPLE 中的行:

ID 不是唯一的,它是组的 ID

ID、姓名、姓氏、UPD、已检查

4345,JOHN,DOE,1 - 这个不存在(他的 ID 不存在) '#PEOPLE,因为它是从现在已更改的早期 #PEOPLE 的早期合并中插入的

879,MARY,HON,1 - 这个存在于#PEOPLE

9875,CHRISTIAN,TROY,1 - 这个与该行的不匹配,但他的 ID 存在 在人物和#PEOPLE

因此,从这个列表中,我希望 JOHN DOE 保持原样,因为他的 ID 没有在#PEOPLE 中退出并且 CHRISTIAN TROY 得到更新,其中 UPD 将为 NULL 并且 CHANGE = CURRENT_TIMESTAMP 但前提是 UPD 不为 null 并且 CHANGE为空,因为他的 ID 存在于 PEOPLE 和 #PEOPLE 但整行不匹配。

MERGE INTO PEOPLE WITH (HOLDLOCK) AS target
USING #PEOPLE AS source

 on isnull(target.ID,'') = isnull(source.ID,'') 
 and isnull(target.NAME,'') = isnull(source.NAME,'') 
 and isnull(target.SURNAME,'') = isnull(source.SURNAME,'') 

WHEN MATCHED THEN 
    UPDATE SET target.UPD = 1
WHEN NOT MATCHED BY TARGET THEN
    INSERT (ID,NAME,SURNAME,UPD) 
    VALUES (source.ID ,source.NAME ,source.SURNAME,1)

WHEN NOT MATCHED BY SOURCE and target.UPD is not null and target.CHANGE is null THEN
  update set UPD = NULL,target.CHANGE  = CURRENT_TIMESTAMP

有什么想法吗?

【问题讨论】:

    标签: sql sql-server tsql sql-merge


    【解决方案1】:

    阅读所有这些内容有点困难,但据我所知,您的表中没有任何 FK,这就是为什么您必须在合并后进行更新。

    您可以使用 OUTPUT,但也许最简单的方法是进行这样的更新。如果匹配 UPD=2 并且如果是,则插入 UPD = 3.. 所以现在你在 UPD = 1 上有那些不匹配的,所以你可以看到#People 中的 ID 是什么,然后更新它们:

    MERGE INTO PEOPLE WITH (HOLDLOCK) AS target
    USING #PEOPLE AS source
    
     on isnull(target.ID,'') = isnull(source.ID,'') 
     and isnull(target.NAME,'') = isnull(source.NAME,'') 
     and isnull(target.SURNAME,'') = isnull(source.SURNAME,'') 
    
    WHEN MATCHED THEN 
        UPDATE SET target.UPD = 2
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (ID,NAME,SURNAME,UPD) 
        VALUES (source.ID ,source.NAME ,source.SURNAME,3)
    
    ;
    
    UPDATE PEOPLE set UPD = null,CHANGE = CURRENT_TIMESTAMP where UPD = 1 and CHANGE is null and ID in (Select distinct ID from #PEOPLE);
    UPDATE PEOPLE set UPD = 1 where (UPD =2 or UPD=3) and MB in (Select distinct MB from #PEOPLE);
    

    【讨论】:

    • 是的,应该这样做。 tnx!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多