我试图在执行SQL合并操作时增加项目代码
我有两个桌子。一个拥有很多信息,包括客户和项目。我想将客户名称和项目名称从一个表合并到另一个表。这篇文章很完美,向我展示了如何做我需要做的事情
但是,我需要维护一个项目编号,该编号在每次添加一条记录时都会递增,并且在您编辑客户或项目名称时不予理会。如果项目被删除,那么我们从下一个可用号码继续。我试图使用分区上的行号来执行此操作,但是它没有给我正确的项目数。
使用文章示例并提供可视化效果,我需要另一列名为Type的食物或饮料作为答案并获得
Item Cost Code Type
Tea 10 1 Drink
Coffee 12 2 Drink
Muffin 11 1 Food
Biscuit 4 2 Food
答案 0 :(得分:1)
我将使用链接提供的示例中的数据,并添加更多数据以确保可以覆盖所有情况,因此首先让我们从这些表开始并填充它们。
--Create a target table
Declare @Products TABLE
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100),
ProductNumber int,
ProductType VARCHAR(100),
Rate MONEY
)
--Insert records into target table
INSERT INTO @Products
VALUES
(1, 'Tea', 1,'Drink',10.00),
(2, 'Coffee', 2,'Drink', 20.00),
(3, 'BiscuitX1', 1,'Food', 45.00) ,
(4, 'Muffin', 2,'Food', 30.00),
(5, 'BiscuitX2', 3,'Food', 40.00),
(6, 'BiscuitX3', 4,'Food', 45.00),
(7, 'Donut', 5, 'Food', 30.00),
(8, 'BiscuitX4', 6,'Food', 40.00),
(9, 'BiscuitX5', 7,'Food', 45.00)
--Create source table
Declare @UpdatedProducts TABLE
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100),
ProductNumber int,
ProductType VARCHAR(100),
Rate MONEY
)
--Insert records into source table
INSERT INTO @UpdatedProducts
VALUES
(1, 'Tea', 0,'Drink', 10.00),
(2, 'Coffee', 0,'Drink', 25.00),
(4, 'Muffin', 0,'Food', 35.00),
(7, 'Donut', 0, 'Food', 30.00),
(10, 'Pizza', 0,'Food', 60.00),
(11, 'PizzaLarge', 0,'Food', 80.00)
您可以看到我添加了ProductNumber和ProductType。 对于@UpdatedProducts表,我假设您没有产品编号,如果没有,则可以直接合并,如果没有,则需要找到它。
因此,让我们首先更新@UpdatedProducts中的ProductNumber
;with cte as (
select u.ProductID,u.ProductName,u.ProductType,u.Rate
,coalesce(p.ProductNumber,row_number() over (partition by u.ProductType order by u.ProductID)
+(select max(pp.ProductNumber) from @Products pp where pp.ProductType=u.ProductType)
-(select Count(*) from @UpdatedProducts uu
inner join @Products ppp on ppp.ProductID=uu.ProductID
where uu.ProductType=u.ProductType)) [ProductNumber]
from @UpdatedProducts u
left outer join @Products p on p.ProductID=u.ProductID
)
update a
set a.[ProductNumber]=cte.[ProductNumber]
From @UpdatedProducts a
inner join cte on cte.ProductID=a.ProductID
我没有找到直接将其放入合并的方法。
更新后@UpdatedProducts的结果如下:-
ProductID ProductName ProductNumber ProductType Rate
========= =========== ============= =========== ====
1 Tea 1 Drink 10.00
2 Coffee 2 Drink 25.00
4 Muffin 2 Food 35.00
7 Donut 5 Food 30.00
10 Pizza 8 Food 60.00
11 PizzaLarge 9 Food 80.00
所以现在我们可以进行直接合并,如下所示:-
--Synchronize the target table with refreshed data from source table
MERGE @Products AS TARGET
USING @UpdatedProducts AS SOURCE
ON (TARGET.ProductID = SOURCE.ProductID)
--When records are matched, update the records if there is any change
WHEN MATCHED AND TARGET.ProductName <> SOURCE.ProductName OR TARGET.Rate <> SOURCE.Rate
THEN UPDATE SET TARGET.ProductName = SOURCE.ProductName, TARGET.Rate = SOURCE.Rate ,TARGET.ProductNumber= TARGET.ProductNumber --left alone on edit
--When no records are matched, insert the incoming records from source table to target table
WHEN NOT MATCHED BY TARGET
THEN INSERT (ProductID, ProductName, Rate,ProductNumber,ProductType)
VALUES (SOURCE.ProductID, SOURCE.ProductName, SOURCE.Rate,SOURCE.ProductNumber,SOURCE.ProductType)-- increments every time a record is added
--When there is a row that exists in target and same record does not exist in source then delete this record target
WHEN NOT MATCHED BY SOURCE
THEN DELETE
--$action specifies a column of type nvarchar(10) in the OUTPUT clause that returns
--one of three values for each row: 'INSERT', 'UPDATE', or 'DELETE' according to the action that was performed on that row
OUTPUT $action,
DELETED.ProductID AS TargetProductID,
DELETED.ProductName AS TargetProductName,
DELETED.Rate AS TargetRate,
INSERTED.ProductID AS SourceProductID,
INSERTED.ProductName AS SourceProductName,
INSERTED.Rate AS SourceRate;
SELECT * FROM @Products
@Products的结果如下:-
ProductID ProductName ProductNumber ProductType Rate
========= =========== ============= =========== ====
1 Tea 1 Drink 10.00
2 Coffee 2 Drink 25.00
4 Muffin 2 Food 35.00
7 Donut 5 Food 30.00
10 Pizza 8 Food 60.00
11 PizzaLarge 9 Food 80.00
对于产品编号(1、3、4、6、7),全部被跳过,新食品Pizza的产品编号为8,而PrizzaLarge的产品编号继续为产品9。 希望这会有所帮助。