2

問題に対処するためにSQLを作成しましたが、準備が整っていません。私は何日も運が悪かったので、さまざまなクエリを試してきました。参考までに、このDBを継承したので、以前よりも少し進んでいる可能性があります。

ブリッジテーブルFormulaColorを使用すると、FormulaとColorの間には多対多の関係があります。FormulaColorには列(FormulaId、ColorId、Percentage)があります。

私のビジネス上の問題は、色Aを使用するすべての数式を色B(1%)、C(2.8%)、およびD(96.2%)に変換することです。したがって、数式が現在数式の50%として色Aを使用している場合、その数式の行にB色と0.5%のパーセンテージ、C色の行に1.4%のパーセンテージと行を追加します。 48.1%のパーセンテージのDカラーの場合。

ただし、問題は、色Aを含む特定の数式であり、すでに1つ以上の色B、C、またはDが含まれている可能性があります。その場合、上記で計算したものを追加するだけでパーセンテージを更新する必要があります。

私がこれまでに持っている実際のSQLは次のとおりです。*これは新しい色の1つを処理するためだけのものであることに注意してください(ColorId = 2594)

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;
4

2 に答える 2

1
CREATE TABLE [dbo].[ReplacementInfo](
[OldColorId] [int] NULL,
[NewColorID] [int] NULL,
[Percentage] [float] NULL
) ON [PRIMARY]

Declare @KillColor int
Select @KillColor=1

Select FormulaId 
into #tmp
from dbo.FormulaColor 
where ColorId=@KillColor

Select t1.FormulaId,Coalesce(FC.ColorId,RI.NewColorID) as ColorID,Coalesce(FC.Percentage*RI.Percentage,RI.Percentage) as Percentage
into #tmpInsert
from dbo.ReplacementInfo RI
join #tmp t1 on 1=1
left join dbo.FormulaColor FC on FC.ColorId=RI.NewColorID and t1.FormulaId=FC.FormulaId


Delete FormulaColor  
from #tmpInsert
where #tmpInsert.FormulaId=FormulaColor.FormulaId and #tmpInsert.ColorId=FormulaColor.ColorId

Delete FormulaColor  where ColorId=@KillColor

insert into FormulaColor
Select * from #tmpInsert

Drop Table #tmp
Drop Table #tmpInsert
于 2012-10-31T09:54:20.213 に答える
1

削除@DeletedColorする色のIDと、@Replacement次のように宣言された置換色のテーブルとします。

DECLARE @DeletedColor int;
DECLARE @Replacement TABLE (ColorId int, Percentage float);

問題に取り組む1つの方法は、次のようになります。

  1. すべての数式に追加する実際の色の値を準備します。

    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、置換色の最終的なパーセンテージを形成します。

  2. FormulaColor作成したばかりの行セットから既存の色を更新します。

    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
    ;
    
  3. 新しい行セットの色を、それらの色を含まない数式に挿入します。

    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
    ;
    

当然、複数のステートメントを使用して実際のテーブルを変更するため、トランザクションで変更を実行して、それらのアトミック性を確保するのが最善です。

于 2012-10-31T20:09:49.893 に答える