Sql 在源表中更改姓氏时出现错误的Merge语句
我在一个临时数据库中有一个名为payroll的源表。我正在使用Merge语句将员工数据从Staging插入到费用数据库。一旦员工结婚并更改了姓氏,我会遇到以下错误: MERGE语句多次尝试更新或删除同一行。当目标行与多个源行匹配时,会发生这种情况。MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组 我在Sql 在源表中更改姓氏时出现错误的Merge语句,sql,tsql,sql-server-2016,Sql,Tsql,Sql Server 2016,我在一个临时数据库中有一个名为payroll的源表。我正在使用Merge语句将员工数据从Staging插入到费用数据库。一旦员工结婚并更改了姓氏,我会遇到以下错误: MERGE语句多次尝试更新或删除同一行。当目标行与多个源行匹配时,会发生这种情况。MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组 我在Employee表中的EmployeeID上有一个唯一的索引。例如,一个月后,我收到一个文件,其唯一id为10072
Employee
表中的EmployeeID
上有一个唯一的索引。例如,一个月后,我收到一个文件,其唯一id为10072名Abby和姓氏smith。Abby结婚后,她的姓氏更改为Marshall,但姓氏和员工id相同。我该怎么办
这是我的合并语句
MERGE INTO Dimension.Employee AS T
USING
(
SELECT DISTINCT
LTRIM(RTRIM(EmplID)) AS EmployeeID
,LTRIM(RTRIM(FirstName)) AS FirstName
,LTRIM(RTRIM(LastName)) AS LastName
FROM Staging.PayRoll
) AS S
ON T.EmployeeID = S.EmployeeID
WHEN NOT MATCHED THEN
INSERT (EmployeeID, FirstName, LastName)
VALUES (S.EmployeeID, S.FirstName, S.LastName)
WHEN MATCHED THEN UPDATE SET
T.FirstName = S.FirstName
, T.LastName = S.LastName
;
听起来这段代码为同一个ID生成了两行,当名称更改时,Payroll表有两个EMPID
SELECT DISTINCT
LTRIM(RTRIM(EmplID)) AS EmployeeID
,LTRIM(RTRIM(FirstName)) AS FirstName
,LTRIM(RTRIM(LastName)) AS LastName
FROM Staging.PayRoll
然后,merge语句尝试更新目标表中的同一行两次。
理论上你不能这样做,因为SQL可以以任何顺序返回数据,所以你不能以正确的顺序应用你的2次更新
下面是一个错误示例和可能的解决方案。(对不起,我没有足够的关于工资表的信息来提供更多信息)
表上的所有限制条件是什么?不要使用合并;使用单独的INSERT和UPDATE语句。。。你把事情复杂化了!在您的工资表上运行该查询,如果您要返回重复的ID,那么我们需要找到一种排除旧版本记录的方法。请参阅我添加的其他示例,您可以设法解决您的问题,如果不能,您可以提供有关工资表的更多信息,我可能可以进一步帮助您。是的,它解决了问题。非常感谢您的帮助。@PACRELY我的要求是相同的,但我的表中没有唯一的id列可按id排序。如何确保我不会使用“合并”将源中存在的重复员工id插入目标。
DROP TABLE #Payroll
CREATE TABLE #Payroll (ID INT
,EmplID INT
,Name VARCHAR(10)
)
INSERT INTO #Payroll VALUES
(1,10,'Bill')
,(2,10,'Bill')
,(3,20,'John')
,(4,20,'John')
,(5,30,'Stephen')
,(6,30,'Steven') --EmpID 30 changes his name
--Steven changed name, but the query is generating a duplicate the MERGE will not be happy
SELECT DISTINCT
LTRIM(RTRIM(EmplID)) AS EmployeeID
,LTRIM(RTRIM(Name)) AS FirstName
FROM #Payroll
--Solution
SELECT DISTINCT
LTRIM(RTRIM(P.EmplID)) AS EmployeeID
,LTRIM(RTRIM(P.Name)) AS FirstName
FROM #Payroll P
CROSS APPLY (SELECT TOP 1 * FROM #Payroll T
WHERE T.EmplID = P.EmplID
ORDER BY ID DESC) L
WHERE
L.ID = P.ID