Представьте, что у вас есть магазин и запас. Вы покупаете товары по разным ценам и хотите рассчитать стоимость каждой продажи. Проблема в том, что цены покупки не фиксированы, и у вас могут быть продажи, когда вы продаете товары из разных покупок со смешанными ценами покупки. Затраты должны быть рассчитаны в виде "первым пришел - первым вышел" -principle: сначала вы продаете самые старые товары на складе.
Например, это может произойти:
2018-10-01: Вы покупаете 6 единиц товара "Product1" по 10 долларов за штуку и кладете их в свой запас.
2018-10-04: клиент хочет 2 товара "Product1". Вы пойдете в свой запас и продаете 2 вещи, которые вы купили за 10,00 $ каждая.
2018-11-01: Вы покупаете 8 единиц товара "Product1" по 8 долларов за штуку и кладете их в свой запас.
2018-11-06: клиент хочет 7 товаров "Product1". Вы пойдете на свой склад и продадите 4 предмета, которые вы купили за 10,00 долларов США каждый, и 3 предмета, которые вы купили за 8,00 долларов США каждый.
2018-12-01: Вы покупаете 4 товара "Product1" по 12,00 долларов каждая.
2018-12-10: клиент хочет 6 товаров "Product1". Вы перейдете на свой склад и продадите 5 предметов, которые вы купили за 8,00 долларов США каждый, и 1 предмет, который вы купили за 12,00 долларов США.
Таким образом, пытаясь поместить это в 2 таблицы:
стол: покупки
purchase | product | amount | purchase price per item| date |
1 1 6 10.00 2018-10-01
2 1 8 8.00 2018-11-01
3 1 4 12.00 2018-12-01
таблица: продажи
sale | product | amount | date | costs
1 1 2 2018-10-04 ??
2 1 7 2018-11-06 ??
3 1 6 2018-12-10 ??
Значения в sales.costs должны быть:
Sale 1: 2*10.00 = 20.00
Sale 2: 4*10.00 + 3*8.00 = 64.00
Sale 3: 5*8.00 + 1*12.00 = 52.00
Любые идеи, если/как можно было бы рассчитать это в MySql 5.6 с оператором UPDATE? Я должен признать, что у меня даже нет идеи, как начать здесь или что попробовать.
Прежде всего, я добавляю новую таблицу под названием stock
. Внутри этой таблицы я храню каждое изменение на складе. Это выглядит так:
purchase | sold | date |
1 2 2018-10-04
1 4 2018-11-06
2 3 2018-11-06
2 5 2018-12-10
3 1 2018-12-10
Вы можете заполнить эту таблицу TRIGGER
если хотите, или вручную. Теперь я использую этот скрипт:
SET @toSell:=5;
SELECT s.stock, p.price, LEAST( s.stock, @toSell ) AS toSell , @toSell * p.price AS totalPrice, @toSell := @toSell - LEAST( s.stock, @toSell ) AS stillNeeded
FROM (
SELECT p.purchase, SUM( s.sold ) AS 'sold', p.amount, IFNULL( p.amount - SUM( s.sold ) , p.amount ) AS 'stock'
FROM purchases AS p
LEFT OUTER JOIN stock AS s ON p.purchase = s.purchase
GROUP BY p.purchase
ORDER BY p.date
) AS s
RIGHT OUTER JOIN purchases AS p ON s.purchase = p.purchase
WHERE s.stock >0 AND LEAST( s.stock, @toSell ) > 0;
Рассчитать стоимость каждой продажи. В начале я определяю переменную, содержащую количество предметов для продажи. Эта переменная будет обрабатываться в каждом ряду. Внутренний SELECT
- это ЛЕВОЕ ВНЕШНЕЕ LEFT OUTER JOIN
чтобы получить количество предметов, включенных в запас каждой покупки, упорядоченной по дате, чтобы сначала использовать предметы старины (FIFO).
Второй SELECT
теперь использует стоковые позиции и сокращает переменную строку за строкой, пока не будет больше элементов, где это необходимо. Просто надо SUM
в totalPrice
колонку, чтобы получить затраты.
Чтобы проверить скрипт, я добавляю новую строку/покупку
4 | 1 | 10 | 5 | 2019-02-04
Когда вы запустите этот скрипт с SET @toSell:=2
результат будет выглядеть так:
stock | price | toSell | totalPrice | stillNeeded
3 12 2 24 0
И с SET @toSell:=5
stock | price | toSell | totalPrice | stillNeeded
3 12 3 60 2
10 5 2 10 0
Надеюсь, поможет :)