开发者

How can I merge two tables without a primary key (or how to have the leftovers from a merge get deleted)?

Say I have these two tables:

     Table A                             Table B  
_______________________            _______________________
 Id | Description                    Id | Description
-----------------------            -----------------------
 1  | Some Val                       1  | Some Val                      
 2  | More Data                      2  | More Data
 2  | Even More                      2  | Less Is More
 2  | More again                     3  | This Changed
 3  | Other Values                   4  | these are random             
 3  | But Not this                 ------------------------  
 4  | these are random             
-----------------------

How can I do a merge to Table A of Table B's changes and get this:

     Table A                       
_______________________            
 Id | Description                  
-----------------------            
 1  | Some Val                     
 2  | More Data                      
 2  | Less Is More
 3  | This Changed
 4  | these are random             
-----------------------

When I try something like this:

merge TableA as target
using (select Id, Description
       from   TableB) 
       as source (Id, Description)
on (target.Id =开发者_如何学Python source.Id)             
when MATCHED then
    update set Id = source.Id, Description = source.Description
when NOT MATCHED then
    insert (Id, Description)
    values (source.Id, source.Description);

I get this error:

The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.

That is because Id is not unique. I can add Description, but then it will never update. That means that changes will orphan rows.

What I really need is a way to say: leave what matches, insert what is missing and delete the rest.

How can I do that delete part?

NOTE: I realized that Table A is really just taking all the values of Table B. But I still want to merge because in practice, very little will be changing between these tables. A full truncate and re-insert is overkill.


merge TableA as target 
using (select * from   TableB) as source 
on ( target.id = source.id AND target.description = source.description )             
--when MATCHED then
    --update set id = source.id, description = source.description
when NOT MATCHED then
    insert (id, description)
    values (source.id, source.description)
when NOT MATCHED BY source then DELETE; 


Should have searched just a bit longer. Needed the the NOT MATCH ON SOURCE option:

merge TableA as target
using (select Id, Description
       from   TableB) 
       as source (Id, Description)
on (target.Id = source.Id)             
when NOT MATCHED BY SOURCE then DELETE    
when NOT MATCHED then
    insert (Id, Description)
    values (source.Id, source.Description);   
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜