Полагаю, вы собираетесь сделать это в триггере. Таким образом, «хитрость» заключается в том, чтобы сработать, когда продажа будет выполнена (разработка, ЕСЛИ она может быть выполнена, является другой проблемой). Для этого присвойте значение 0 строкам, в которых совокупное количество меньше продажи, 1 - строке, в которой продажа может быть окончательно исполнена, и 2 после этого. Я предположил, что есть уникальный идентификатор строки, чтобы справиться с несколькими записями инвентаризации за одну и ту же дату - в моем случае - инвентарь.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)