0
UPDATE Products 
SET Products.Quantity = Products.Quantity + ShoppingCart.Quantity
FROM Products INNER JOIN ShoppingCart
    ON ShoppingCart.ProductID = Products.ProductID 
WHERE ShoppingCart.DateAdded < GETDATE()- 7
DELETE FROM ShoppingCart
WHERE DateAdded < GETDATE()- 7 

そして、このクエリはこの仕事をする必要があります:

ShoppingCart に追加されてから 7 日を経過した商品は削除され、その数量はその商品の販売可能な数量に戻されます。ただし、ここでの問題は、最初の製品の数量のみが Products.Quantity フィールドに追加されることです。残りはカウントされず、製品テーブルに追加されます..

4

1 に答える 1

0

次の初期データを想定しました: 製品:

PRODUCTID   QUANTITY
1             10
2            210
3              0

ショッピングカート:

CARTID  PRODUCTID   QUANTITY    DATEADDED
21          1           3           2012-11-20
24          1           1           2012-11-19
22          2           2           2012-11-25
23          3           3           2012-11-20

次の出力が得られます。

製品:

PRODUCTID   QUANTITY
1             14
2            210
3              3

Products のすべての行で、Quantity が "x" 回更新されます。ここで、"x" は、ShoppingCart の一致する行の数です。ただし、反復ごとに「Products.Quantity」が保持する値は初期値であるため、最終的な結果は、Products.Quantity の初期値と、ShoppingCart で最後に一致したレコードの Quantity 値を加算したものになります。

たとえば、上記のデータセットでは、次の同等のアクションが製品 1 のデータベースで発生します。

UPDATE Products SET Quantity = 10 + 1 WHERE ProductId = 1;
UPDATE Products SET Quantity = 10 + 3 WHERE ProductId = 1;

したがって、最終的な値は 13 であり、予想される 14 ではありません。基本的に、INNER JOIN で評価された最後の行が優先され、残りは事実上無視されます。

これを回避するには、set コマンドを実行する前にデータを集約する必要があります。以下がうまくいくと思います。インライン ビューで各製品の期限切れの数量をすべて合計し、その値を更新に使用しています。

UPDATE Products 
SET Products.Quantity = Products.Quantity + Expired.Quantity
FROM Products 
INNER JOIN (SELECT S.ProductId, SUM(S.Quantity) AS Quantity 
              FROM ShoppingCart S 
             WHERE S.DateAdded < GETDATE()- 7
          GROUP BY S.ProductId) AS Expired
    ON Expired.ProductID = Products.ProductID 

これをテストするためにSQL Fiddleを使用しました。

于 2012-11-28T02:35:42.137 に答える