Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在源表中更改姓氏时出现错误的Merge语句_Sql_Tsql_Sql Server 2016 - Fatal编程技术网

Sql 在源表中更改姓氏时出现错误的Merge语句

Sql 在源表中更改姓氏时出现错误的Merge语句,sql,tsql,sql-server-2016,Sql,Tsql,Sql Server 2016,我在一个临时数据库中有一个名为payroll的源表。我正在使用Merge语句将员工数据从Staging插入到费用数据库。一旦员工结婚并更改了姓氏,我会遇到以下错误: MERGE语句多次尝试更新或删除同一行。当目标行与多个源行匹配时,会发生这种情况。MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组 我在Employee表中的EmployeeID上有一个唯一的索引。例如,一个月后,我收到一个文件,其唯一id为10072

我在一个临时数据库中有一个名为payroll的源表。我正在使用Merge语句将员工数据从Staging插入到费用数据库。一旦员工结婚并更改了姓氏,我会遇到以下错误:

MERGE语句多次尝试更新或删除同一行。当目标行与多个源行匹配时,会发生这种情况。MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组

我在
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