来源表
Id, Name, Address
1 A #202
1 A #203
1 A #204
2 A #202
目标表
Id, Name, Address
1 A NULL
合并后
Id, Name, Address
1 A #202
2 A #202
我正在使用这个SQL
create table #S (ID int, Name varchar(25) NULL, Address varchar(25) NULL)
create table #T (ID int, Name varchar(25) NULL, Address varchar(25) NULL)
INSERT #S values(1, 'A', '#202')
INSERT #S values(1, 'A', '#203')
INSERT #S values(1, 'A', '#203')
INSERT #S values(1, 'A', '#204')
INSERT #T values(1, 'A', NULL)
MERGE #T USING
(
Select id, name, address
from #S
) AS S(id,name,address)
on #T.id=S.id and #T.Name=S.Name
when not matched THEN
INSERT values(S.id,S.Name, S.Address)
when matched then
update set Address = S.Address;
GO
Select * from #T
GO
Select * from #S
GO
这会导致错误
Msg 8672,Level 16,State 1,Line 18
MERGE语句尝试多次更新或删除同一行。当目标行与多个源行匹配时会发生这种情况。 MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组。
我想从三个匹配值中的任何一个更新A中带有地址值的行。怎么做?
答案 0 :(得分:23)
#S
中的四个值中的任何一个都将匹配目标表的单行值(#S中的所有值都有id = 1且name ='A' - 所以它们都匹配目标中的单行) ,因此这个值将被更新四次 - 这就是错误所说的,而且它是完全正确的。
你真的想在这里实现什么?
是否要将地址设置为源表中的第一个值?在子选择中使用TOP 1
子句:
MERGE #T
USING (SELECT TOP 1 id, name, address FROM #S) AS S
ON #T.id = S.id AND #T.Name = S.Name
WHEN NOT MATCHED THEN
INSERT VALUES(S.id,S.Name, S.Address)
WHEN MATCHED THEN
UPDATE SET Address = S.Address;
是否要将地址设置为源表中值的随机元素?在子选择中使用TOP 1
和ORDER BY NEWID()
子句:
MERGE #T
USING (SELECT TOP 1 id, name, address FROM #S ORDER BY NEWID()) AS S
ON #T.id = S.id AND #T.Name = S.Name
WHEN NOT MATCHED THEN
INSERT VALUES(S.id,S.Name, S.Address)
WHEN MATCHED THEN
UPDATE SET Address = S.Address;
如果您将四个源行匹配到一个目标行,您将永远无法获得有用的结果 - 您需要知道您真正想要的是什么。
马克
答案 1 :(得分:1)
使用
删除副本select R.*
from (SELECT Customer,Material,Received_date_time,
row_number() over (Partition by Customer, Material
order by Customer,Material,Received_date_time) as rn
from Customer_Table WHERE Status=0
) as R
where R.rn = 1
对于合并你不能有重复,所以你总是要拿起最新的