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);
精彩评论