今天早些时候,我问了这个问题并得到了我正在寻找的答案。现在我有一个后续问题:
我想要的是:
我希望 MERGE 将目标表中的每一列值、每行值与源表中的相应值进行比较,并根据块中分隔的逻辑进行任何OR
更新WHEN MATCHED AND
。
如果块中分隔的任何逻辑为真,我担心我编写的代码(如下图所示)会在THEN UPDATE SET
块中列出更新。OR
WHEN MATCHED AND
如果我的预感是正确的,您对如何重写代码以使其表现得像我希望的那样有什么建议吗?
今天早些时候,我问了这个问题并得到了我正在寻找的答案。现在我有一个后续问题:
我想要的是:
我希望 MERGE 将目标表中的每一列值、每行值与源表中的相应值进行比较,并根据块中分隔的逻辑进行任何OR
更新WHEN MATCHED AND
。
如果块中分隔的任何逻辑为真,我担心我编写的代码(如下图所示)会在THEN UPDATE SET
块中列出更新。OR
WHEN MATCHED AND
如果我的预感是正确的,您对如何重写代码以使其表现得像我希望的那样有什么建议吗?
没有您的数据,也不想从图像中重新输入您的查询,我创建了一个示例,我认为该示例演示了您想要什么:
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
结果:
ID Col1 Col2
----------- ----------- -----------
1 1 4
2 5 2
3 7 8
如果它已经有一个列值,那么关键是用来COALESCE
避免更新一个列值(我认为这是你想要实现的)
我不确定我是否理解这个问题 - 你的意思是......好吧,我不确定你的意思。减去额外的尾随 OR,您有两个条件。如果其中一个(或两者)评估为 TRUE,则目标表将由 THEN UPDATE 更新
但是,您在 unique_key 上进行 MATCHing,第一个条件(s.unique_key IS NOT NULL AND t.unique_key IS NULL)永远不会为真,因为如果它为真,那么记录将不会匹配。所以 OR 的第一部分可以忽略。
此外,由于记录在 unique_key 上匹配,因此使用 unique_key 的源值更新目标是完全多余的——它们已经相同。
因此,正如目前所写,您的 MERGE 是:
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