问题
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