我在登台数据库中有一个名为payroll的源表。我正在使用Merge语句将员工数据从Staging插入到Expense数据库。一旦员工结婚并更改了他们的姓氏,我就会收到此错误:
MERGE语句尝试多次更新或删除同一行。当目标行与多个源行匹配时会发生这种情况。 MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组。
我在EmployeeID
表格中的Employee
上有一个唯一索引。举个例子,我得到一个文件,其唯一身份证号为10072,名字为Abby,姓氏为史密斯,一旦艾比结婚,她的姓氏将更改为马歇尔,但姓名和员工身份相同。我该怎么办?
这是我的合并声明。
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
;
答案 0 :(得分:1)
听起来这段代码为同一个ID生成了2行,当名称更改时,Payroll表有2个EmpID。
SELECT DISTINCT
LTRIM(RTRIM(EmplID)) AS EmployeeID
,LTRIM(RTRIM(FirstName)) AS FirstName
,LTRIM(RTRIM(LastName)) AS LastName
FROM Staging.PayRoll
然后,merge语句尝试两次更新Target表中的同一行。 理论上你不能这样做,因为SQL可以在任何ORDER中返回数据,因此你不能以正确的顺序应用你的2个更新。
以下是错误和可能解决方案的示例。 (对不起,我没有足够的关于工资表的信息来提供更多信息)
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