我有@Products和@TempProducts表。我想从@TempProducts更新@Products。
我的代码:
DECLARE @Products TABLE(
Id INT,
Name NVARCHAR(255),
Description NVARCHAR(255));
DECLARE @TempProducts TABLE(
RowNumber int,
Id INT,
Name NVARCHAR(255),
Description NVARCHAR(255));
INSERT INTO @Products(Id,Name,Description) VALUES(1,'Name1','Desc1');
INSERT INTO @TempProducts(RowNumber,Id,Name,Description)
VALUES(1,1,'NewName1',NULL);
INSERT INTO @TempProducts(RowNumber,Id,Name,Description)
VALUES(2,1,NULL,'NewDesc1');
INSERT INTO @TempProducts(RowNumber,Id,Name,Description)
VALUES(3,1,NULL,'NewDesc2');
INSERT INTO @TempProducts(RowNumber,Id,Name,Description)
VALUES(4,1,'NewName2',NULL);
WITH TP AS
(
SELECT TOP (100000) RowNumber,Id,Name,DESCRIPTION
FROM @TempProducts
ORDER BY RowNumber ASC
)
UPDATE P
SET Name = ISNULL(TP.Name,P.Name),
Description = ISNULL(TP.Description,P.Description)
FROM @Products P
INNER JOIN TP
ON P.Id = TP.Id
SELECT * FROM @Products
预期:
Id Name Description
---------------------------
1 NewName2 NewDesc2
但是得到:
Id Name Description
---------------------------
1 NewName1 NewDesc1
请注意,我通过ORDER BY RowNumber进行排序意味着首先更新RowNumber1然后是第二个,依此类推。
答案 0 :(得分:3)
如果有多个匹配项,则SQL Server不会指定要更新的内容。如果您希望更新最后一个(或第一个)值,则使用窗口函数来查找它:
WITH TP AS (
SELECT t.*,
ROW_NUMBER() OVER (PARRTITION BY ID ORDER BY RowNumber DESC) as seqnum
FROM (SELECT TOP (100000) tp.*
FROM @TempProducts ORDER BY RowNumber ASC
) t
)
UPDATE P
SET Name = ISNULL(TP.Name,P.Name),
Description = ISNULL(TP.Description,P.Description)
FROM @Products P INNER JOIN
TP
ON P.Id = TP.Id AND seqnum = 1;
答案 1 :(得分:1)
指定FROM子句以提供条件时要小心 用于更新操作。 UPDATE语句的结果是 如果语句包含不是的FROM子句,则为undefined 以这样的方式指定,每个只有一个值可用 更新的列出现,即UPDATE语句是否 不确定。
我会这样做:
UPDATE P SET Name = ISNULL(ca1.Name, P.Name), Description = ISNULL(ca2.Description, P.Description)
FROM @Products P
OUTER APPLY(SELECT TOP 1 Name FROM @TempProducts WHERE ID = p.ID AND Name IS NOT NULL ORDER BY RowNumber DESC) ca1
OUTER APPLY(SELECT TOP 1 Description FROM @TempProducts WHERE ID = p.ID AND Description IS NOT NULL ORDER BY RowNumber DESC) ca2