如何根据到期日更新库存 table 数量?

How to update stock table quantity on the basis of expiry date?

大家好,我有 table 库存,列如下

Item_ID  | Expiry_Date | Quantity | Rate
 cB0001  | 01-18-2021  |     5    | 150
 cB0001  | 12-08-2020  |     3    | 145
 cB0001  | 02-15-2021  |     25   | 155

注意:费率不是问题我只想根据到期日和可用数量更新库存 Table 数量。

现在我想从先过期的库存中向客户销售商品 cB0001 数量 : 10 的库存。现在的问题是销售数量是 10,我想减去到期日 01-18-2021 的数量 5 和到期日 12-08-2020 的 3 和 02-15-2021 的 2。基本上我想使用一个查询来实现 FIFO 逻辑。我想使用此

更新库存 table 数量
update stock set quantity = quantity - '10' where item_id = 'cB0001' and expiry_Date < Now()

但这并没有给出准确的结果。如何解决这个问题?你有什么想法吗?

希望你能理解我的问题

我假设您打算在触发器中执行此操作。所以 'trick' 是计算销售何时完成(计算是否可以完成是另一个问题)。为此,将值 0 分配给累计数量小于销售的行,将 1 分配给销售最终可以完成的行,然后分配 2。我假设有一个唯一的行标识符来处理同一日期的多个库存条目 - 在我的例子中 inventory.id

drop table if exists inventory,sales;
create table inventory
(id int auto_increment primary key,Item_ID varchar(20),  Expiry_Date date,  Quantity int, Rate int);

create table sales (item_id varchar(20), quantity int);

insert into inventory values
( null,'cB0001'  , str_to_date('01-18-2021','%m-%d-%Y'),     5    , 150),
( null,'cB0001'  , str_to_date('12-08-2020','%m-%d-%Y'),     3    , 145),
( null,'cB0001'  , str_to_date('02-15-2021','%m-%d-%Y'),     25   , 155),
( null,'cB0001'  , str_to_date('02-15-2021','%m-%d-%Y'),     10   , 155),
( null,'cB0001'  , str_to_date('02-15-2021','%m-%d-%Y'),     10   , 155),
( null,'cB0001'  , str_to_date('02-15-2021','%m-%d-%Y'),     10   , 155),
( null,'cB0002'  , str_to_date('02-15-2021','%m-%d-%Y'),     30   , 155);

drop trigger if exists t;
delimiter $$
create trigger t after insert on sales
for each row 
begin
update  inventory  left join
(select s.*,
         if(fst = 0, @runqty:=@runqty+quantity,@runqty:=@runqty) qty
from
(
select *,
         @t:=@t+quantity cumqty,
         if(@t>=@sale,if(@p>=1,2,@p:=1),@p:=0) fst
from inventory
cross join (select @t:=0,@p:=0,@sale:=new.quantity) t
where quantity > 0 and item_id = new.item_id
order by item_id,expiry_date
) s
cross join (select @runqty:=0) r
where fst in (0,1)
) a
on a.id = inventory.id 
set inventory.quantity = case when fst = 0 then 0 
                                      when fst = 1 then inventory.quantity - (new.quantity - a.qty)
                                 else inventory.quantity
                                 end;

end $$

delimiter ;


MariaDB [sandbox]> insert into sales values('cb0001',10);
Query OK, 1 row affected (0.095 sec)

MariaDB [sandbox]> select * from inventory order by item_id,expiry_date;
+----+---------+-------------+----------+------+
| id | Item_ID | Expiry_Date | Quantity | Rate |
+----+---------+-------------+----------+------+
|  2 | cB0001  | 2020-12-08  |        0 |  145 |
|  1 | cB0001  | 2021-01-18  |        0 |  150 |
|  3 | cB0001  | 2021-02-15  |       23 |  155 |
|  4 | cB0001  | 2021-02-15  |       10 |  155 |
|  5 | cB0001  | 2021-02-15  |       10 |  155 |
|  6 | cB0001  | 2021-02-15  |       10 |  155 |
|  7 | cB0002  | 2021-02-15  |       30 |  155 |
+----+---------+-------------+----------+------+
7 rows in set (0.001 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> insert into sales values('cb0001',25);
Query OK, 1 row affected (0.111 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select * from inventory order by item_id,expiry_date;
+----+---------+-------------+----------+------+
| id | Item_ID | Expiry_Date | Quantity | Rate |
+----+---------+-------------+----------+------+
|  2 | cB0001  | 2020-12-08  |        0 |  145 |
|  1 | cB0001  | 2021-01-18  |        0 |  150 |
|  3 | cB0001  | 2021-02-15  |        0 |  155 |
|  4 | cB0001  | 2021-02-15  |        8 |  155 |
|  5 | cB0001  | 2021-02-15  |       10 |  155 |
|  6 | cB0001  | 2021-02-15  |       10 |  155 |
|  7 | cB0002  | 2021-02-15  |       30 |  155 |
+----+---------+-------------+----------+------+
7 rows in set (0.001 sec)