MERGE - UPDATE column values separately, based on logic in WHEN MATCHED block

我与影子孤独终老i 提交于 2020-02-08 10:05:08

问题


Earlier today, I asked this question and got the answer I was looking for. Now I have a follow-up question:

What I want:

I want the MERGE to compare each column value, per row, in the target table against the corresponding value in the source table, and make any updates based on the logic separated by OR in the WHEN MATCHED AND block.

I am afraid that the code I've written (pictured below) will make the updates listed in the THEN UPDATE SET block if any of the logic separated by OR in the WHEN MATCHED AND block is true.

If my hunch is correct, do you have any suggestions for how to re-write the code to have it behave like I want it to behave?


回答1:


Not having your data, and not wanting to re-type your query from an image, I created a sample that I think demonstrates what you want:

create table t (ID int not null,Col1 int null,Col2 int null)
create table s (ID int not null,Col1 int null,Col2 int null)

insert into t(ID,Col1,Col2) values (1,1,null),(2,null,2)
insert into s(ID,Col1,Col2) values (1,3,4),(2,5,6),(3,7,8)

;merge into t
using s
on t.ID = s.ID
when not matched then insert (ID,Col1,Col2) values (s.ID,s.Col1,s.Col2)
when matched then update
set Col1 = COALESCE(t.Col1,s.Col1),
Col2 = COALESCE(t.Col2,s.Col2)
;
select * from t

Result:

ID          Col1        Col2
----------- ----------- -----------
1           1           4
2           5           2
3           7           8

Where the key is to use COALESCE to avoid updating a column value if it already has one (which I think is what you're trying to achieve)




回答2:


I'm not sure I understand the question - do you mean... well, I'm not sure what you mean. Minus the extra trailing OR, you have two conditions. If either (or both) of these evaluate to TRUE, the target table will be updated by the THEN UPDATE

However, you are MATCHing on unique_key, and the first condition (s.unique_key IS NOT NULL AND t.unique_key IS NULL) will never be true, because if it were true then the records would not be matched. So the first part of the OR can be ignored.

Also, since the records are MATCHED on unique_key, it is completely redundant to update the target with the source value of unique_key - they are already the same.

Thus, as it is currently written, your MERGE is:

MERGE dbo.input311 AS T
USING dbo.input311staging AS S
ON S.unique_key = S.unique_key
WHEN NOT MATCHED BY TARGET THEN
   INSERT
     -- insert statement I'm too lazy to type
WHEN MATCHED AND s.created_date IS NOT NULL AND t.created_date IS NULL THEN
   UPDATE SET t.created_date = s.created_date


来源:https://stackoverflow.com/questions/13924973/merge-update-column-values-separately-based-on-logic-in-when-matched-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!