店舗が受け取るすべての注文を格納する購入テーブルがあります。場合によっては、別の費用で商品を再注文する必要があります。販売取引を行うとき、購入日によって決定される FIFO (First In, First Our) システムを使用して、販売されたアイテムの総コストを決定できる必要があります。
これが私のテーブルの外観です
CREATE TABLE `purchases` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`item_id` int(11) unsigned NOT NULL,
`purchased_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`cost` decimal(10,2) unsigned NOT NULL,
`availableQty` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `item_id` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `purchases` (`id`, `item_id`, `purchased_on`, `cost`, `availableQty`) VALUES
(1, 1, '2015-01-13 23:50:09', '1.00', 10),
(2, 1, '2015-01-13 23:50:10', '0.90', 20),
(3, 1, '2015-01-13 23:50:11', '0.80', 50),
(4, 2, '2015-01-13 23:50:11', '10.80', 18),
(5, 2, '2015-01-13 23:50:11', '20.25', 235);
上記のデータを使用して、誰かが item_id = 1 の 40 ユニットを購入したい場合、コストは (10 X 1.00) + (20 X 0.90) + (10 X 0.80) = 36 のように計算されます。item_id = 1 のこのトランザクションの合計費用は $36 です。
しかし今、 availableQty
列を新しい使用可能な値で更新する必要があります。
列の値に基づいてavailableQty
、行 1 と 2 の列の値は 0 で availableQty
、同じ列の行 3 には 40 が残っている必要があります。
トランザクションのコストを計算するために、コスト計算を行うこのクエリを作成できました。
SET @orgMyQty = 40;
SET @myQty = @orgMyQty;
SELECT SUM(cost) AS total_cost, SUM(availableQty) AS totalAvailable, SUM(availableQty) - @orgMyQty AS RemainingUnites
FROM (
SELECT
CASE WHEN availableQty >= @myQty THEN cost * @myQty
ELSE cost * availableQty END AS cost,
CASE WHEN @myQty > availableQty THEN @myQty := @myQty - availableQty END AS left_over,
availableQty
FROM purchases
WHERE item_id = 1 AND @myQty > 0
ORDER BY purchased_on ASC, item_id ASC
) AS t
しかし、新しい totalAvailable 値で各行を更新するにはどうすればよいでしょうか?
したがって、最終的なレコードは次のようになる必要があります
(1, 1, '2015-01-13 23:50:09', '1.00', 0),
(2, 1, '2015-01-13 23:50:10', '0.90', 0),
(3, 1, '2015-01-13 23:50:11', '0.80', 40),
(4, 2, '2015-01-13 23:50:11', '10.80', 18),
(5, 2, '2015-01-13 23:50:11', '20.25', 235);
だから私の質問はこれです
- UPDATE を正しく実行するには?
- このトランザクションがコミットされるまで他のトランザクションが値を変更できないように、クエリ クエリを使用して更新のために行をロックする方法。select と update の両方のクエリが同じトランザクション内にあることに注意してください。
- コストを計算するためのより良いアプローチはありますか?
値を更新するために次のクエリを試しました
-- これにより、この行で構文エラーが発生します@myQty := CASE WHEN @myQty > availableQty THEN @myQty - availableQty ELSE @myQty END
SET @myQty = 40;
UPDATE data_import.purchases
SET qty = CASE WHEN @myQty = 0 THEN 0
WHEN @myQty > 0 AND availableQty >= @myQty THEN cost * @myQty
ELSE cost * availableQty END,
@myQty := CASE WHEN @myQty > availableQty THEN @myQty - availableQty ELSE @myQty END
WHERE item_id = 1
ORDER BY purchased_on ASC, item_id ASC;
私もこのクエリを試しました
-- there is not syntax error here but only the last column was updated incorrectly.
UPDATE data_import.purchases
SET qty = CASE WHEN @myQty = 0 THEN 0
WHEN @myQty > 0 AND availableQty >= @myQty THEN cost * @myQty
ELSE cost * availableQty END
WHERE item_id = 1 AND @myQty := CASE WHEN @myQty > availableQty THEN @myQty - availableQty ELSE @myQty END
ORDER BY purchased_on ASC;