3つのテーブルがあります(簡略化):
tblOrder(OrderId INT)
tblVariety(VarietyId INT,Stock INT)
tblOrderItem(OrderId,VarietyId,Quantity INT)
注文する場合、これを使用して在庫レベルをドロップします。
UPDATE tblVariety
SET tblVariety.Stock = tblVariety.Stock - tblOrderItem.Quantity
FROM tblVariety
INNER JOIN tblOrderItem ON tblVariety.VarietyId = tblOrderItem.VarietyId
INNER JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId
WHERE tblOrder.OrderId = 1
同じOrderIdに対して同じVarietyIdを持つtblOrderItemに2つの行が存在するまでは問題ありません。この場合、行の1つだけが在庫更新に使用されます。そこに何らかの形でGROUP BY VarietyIdを実行しているようです。
誰かが光を当てることはできますか?どうもありがとう。
私の推測では、簡略化されたスキーマを示したため、特定のOrderIDに対してVarietyID値が繰り返される理由を特定する情報が欠落しています。
複数の行がある場合、SQL Serverは更新のためにそのうちの1つを任意に選択します。
この場合、最初にグループ化する必要があります
UPDATE V
SET
Stock = Stock - foo.SumQuantity
FROM
tblVariety V
JOIN
(SELECT SUM(Quantity) AS SumQuantity, VarietyID
FROM tblOrderItem
JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId
WHERE tblOrder.OrderId = 1
GROUP BY VarietyID
) foo ON V.VarietyId = foo.VarietyId
そうでない場合、重複するOrderID/VarietyIDの組み合わせを許可する場合、OrderItemsテーブルのPKは間違っています(PKはOrderID/VarietyIDであるか、これらは一意に制約される必要があります)
ドキュメントから [〜#〜] update [〜#〜]
UPDATEステートメントの結果は、更新される各列オカレンスに対して1つの値のみが使用できるように指定されていないFROM句がステートメントに含まれている場合、未定義です(言い換えると、 UPDATEステートメントが決定的でない場合)たとえば、次のスクリプトでUPDATEステートメントを指定すると、テーブルsの両方の行がUPDATEステートメントのFROM句の条件を満たしますが、 sのどの行がテーブルtの行の更新に使用されるかは未定義です。
CREATE TABLE s (ColA INT, ColB DECIMAL(10,3))
GO
CREATE TABLE t (ColA INT PRIMARY KEY, ColB DECIMAL(10,3))
GO
INSERT INTO s VALUES(1, 10.0)
INSERT INTO s VALUES(1, 20.0)
INSERT INTO t VALUES(1, 0.0)
GO
UPDATE t
SET t.ColB = t.ColB + s.ColB
FROM t INNER JOIN s ON (t.ColA = s.ColA)
GO
更新を行っています。一度更新されます。
編集:解決するために、orderidとvarietyidで注文項目をグループ化するサブクエリを追加し、金額を合計することができます。