将插入选择转换为更新的SQL
我编写了一些SQL来解决我的问题,但它还没有完全准备好。几天来,我一直在尝试不同的问题,但运气不好。仅供参考,我继承了这个数据库,因此它可能比我以前使用的更先进 使用桥接表FormulaColor,公式和颜色之间存在多对多关系。FormulaColor包含FormulaId、ColorId和Percentage列 我的业务问题是,我们正在将所有使用颜色A的配方转换为颜色B1%、C2.8%和D96.2%。因此,如果一个公式当前使用颜色a作为公式的50%,那么我将为该公式添加一行,B颜色的百分比为.5%,C颜色的百分比为1.4%,D颜色的百分比为48.1% 但问题是,一个包含颜色a的给定公式可能已经包含一个或多个颜色B、C或D。在这种情况下,我需要通过简单地添加上面计算的内容来更新百分比 到目前为止,我拥有的实际sql如下所示*请注意,这仅用于处理1种新颜色ColorId=2594将插入选择转换为更新的SQL,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,我编写了一些SQL来解决我的问题,但它还没有完全准备好。几天来,我一直在尝试不同的问题,但运气不好。仅供参考,我继承了这个数据库,因此它可能比我以前使用的更先进 使用桥接表FormulaColor,公式和颜色之间存在多对多关系。FormulaColor包含FormulaId、ColorId和Percentage列 我的业务问题是,我们正在将所有使用颜色A的配方转换为颜色B1%、C2.8%和D96.2%。因此,如果一个公式当前使用颜色a作为公式的50%,那么我将为该公式添加一行,B颜色的百分比为.
INSERT INTO FormulaColor (FormulaId, ColorId, Percentage)
SELECT FormulaId, 2594 as ColorId, round((.01*FormulaColor.Percentage),2) as Percentage
FROM FormulaColor WHERE ColorId=2595;
DELETE FROM FormulaColor WHERE ColorId = 2595;
我在想我需要的是使用使用@rowscount的upsert方法吗?如果是这样的话,我不知道如何进行更新,将计算出的金额添加到百分比中
任何帮助或资源都将不胜感激
更新
我最终使用了Andriy M的解决方案。如果它能帮助其他人,我将发布我使用的实际SQL
DECLARE @DeletedColor int;
DECLARE @Replacement TABLE (ColorId int, Percentage float);
-- old ColorId getting replaced
SET @DeletedColor = 2595
-- new ColorId's and the percentages needed to recalculate
INSERT INTO @Replacement (ColorId, Percentage) VALUES (2594, .01)
INSERT INTO @Replacement (ColorId, Percentage) VALUES (2521, .028)
INSERT INTO @Replacement (ColorId, Percentage) VALUES (2533, .962)
SELECT
fc.FormulaId,
r.ColorId,
Percentage = round(fc.Percentage * r.Percentage, 2)
INTO #FormulaColor
FROM FormulaColor fc
CROSS JOIN @Replacement r
WHERE fc.ColorId = @DeletedColor
;
UPDATE old
SET old.Percentage = old.Percentage + new.Percentage
FROM FormulaColor old
INNER JOIN #FormulaColor new
ON old.FormulaId = new.FormulaId
AND old.ColorId = new.ColorId
;
INSERT INTO FormulaColor (FormulaId, ColorId, Percentage)
SELECT new.FormulaId, new.ColorId, new.Percentage
FROM #FormulaColor new
LEFT JOIN FormulaColor old
ON old.FormulaId = new.FormulaId
AND old.ColorId = new.ColorId
WHERE old.FormulaId IS NULL
;
DELETE FROM FormulaColor WHERE ColorId = @DeletedColor;
将@DeletedColor作为要删除颜色的ID,@Replacement作为替换颜色表,声明如下:
DECLARE @DeletedColor int;
DECLARE @Replacement TABLE (ColorId int, Percentage float);
解决问题的一种方法是:
DECLARE @DeletedColor int;
DECLARE @Replacement TABLE (ColorId int, Percentage float);
准备要添加到每个配方中的实际颜色值:
SELECT
fc.FormulaId,
r.ColorId,
Percentage = fc.Percentage * r.Percentage
INTO #FormulaColor
FROM FormulaColor fc
CROSS JOIN @Replacement r
WHERE fc.ColorId = @DeletedColor
;
这是为包含@DeletedColor的每个公式创建替换颜色列表。替换表中每种替换颜色的指定百分比由每种配方的@DeletedColor的百分比构成替换颜色的最终百分比
从刚创建的行集合更新现有公式颜色:
UPDATE old
SET old.Percentage = old.Percentage + new.Percentage
FROM FormulaColor old
INNER JOIN #FormulaColor new
ON old.FormulaId = new.FormulaId
AND old.ColorId = new.ColorId
;
将新行集合中的颜色插入不包含这些颜色的公式:
INSERT INTO FormulaColor (FormulaId, ColorId, Percentage)
SELECT new.FormulaId, new.ColorId, new.Percentage
FROM #FormulaColor new
LEFT JOIN FormulaColor old
ON old.FormulaId = new.FormulaId
AND old.ColorId = new.ColorId
WHERE old.FormulaId IS NULL
;
当然,由于您要使用多条语句修改实际表,最好在事务中执行修改,以确保其原子性。旁注:1=1上的加入tmp t1相当于交叉加入tmp t1,我只是想在您不知道的情况下让您知道。谢谢,我将在接下来的几天内对此进行测试,如果有效,请标记您的答案!我必须做一些研究来了解发生了什么,以及如何使用它,比如如何设置@depentedColor。然而,它最终似乎运作良好。非常感谢。
INSERT INTO FormulaColor (FormulaId, ColorId, Percentage)
SELECT new.FormulaId, new.ColorId, new.Percentage
FROM #FormulaColor new
LEFT JOIN FormulaColor old
ON old.FormulaId = new.FormulaId
AND old.ColorId = new.ColorId
WHERE old.FormulaId IS NULL
;