MySql - 使用 FIFO 逻辑更新行的状态

MySql - Update the status of rows using FIFO logic

我在下面的 mysql table 中,如果传递的数量超过 qty_req 值使用 MySql 或 PHP.

征用table:

id part_id qty_req approval_status
1 16 20 0
2 17 30 0
3 16 40 0
4 17 50 0
5 17 60 0

示例:

$update_status=Array ( 
    [0] => Array ( [part_id] => 17 [qty] => 90 )
    [1] => Array ( [part_id] => 16 [qty] => 70 ) 
)

从上面的数组中,90part_id 17 的可用数量。我想在 requisition table 中将 approval_status 更新为 1,对于 part_id 为 17 的行,在以下情况下:

  1. approval_status 更新为1,因为第一行part_id17的数量是30,小于90。

  2. approval_status 更新为1,因为part_id17的第二行的数量是30+50=80,小于90。

  3. 第三行不会更新,因为总数 30+50+60=140 大于 90。

不幸的是,我找不到任何实现此目的的教程。

如有任何帮助,我们将不胜感激。提前致谢。

单个数据:

UPDATE test t1
NATURAL JOIN ( SELECT *, SUM(qty_req) OVER (ORDER BY reg_date) cum_sum
               FROM test
               WHERE part_id = @part_id ) t2
SET t1.approval_status = 1 
WHERE cum_sum <= @qty;

多项数据:

UPDATE test t1
NATURAL JOIN ( SELECT test.*, 
                      SUM(qty_req) OVER (PARTITION BY part_id ORDER BY reg_date) cum_sum,
                      qty
               FROM test
               JOIN JSON_TABLE(@json,
                               '$[*]' COLUMNS ( part_id INT PATH '$.part_id',
                                                qty INT PATH '$.qty')) jsontable USING (part_id) ) t2
SET t1.approval_status = 1 
WHERE cum_sum <= qty;

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=7cf062d81a138657dee78f3026623783

添加了列 reg_date 和唯一索引以提供明确且明确的行排序。


适用于MySQL5.6的解决方案:

UPDATE test t1
NATURAL JOIN ( SELECT t1.part_id,
                      t1.qty_req,
                      t1.approval_status,
                      t1.reg_date,
                      SUM(t2.qty_req) cum_sum
               FROM test t1
               JOIN test t2 USING (part_id)
               WHERE t1.reg_date >= t2.reg_date
               GROUP BY t1.part_id,
                        t1.qty_req,
                        t1.approval_status,
                        t1.reg_date ) t2
JOIN ( SELECT 17 part_id, 90 qty
       UNION ALL
       SELECT 16, 50 ) t3 USING (part_id)
SET t1.approval_status = 1 
WHERE t2.cum_sum <= t3.qty

https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=0aad358941f66d1f385799072237d513

源数据必须形成为查询文本 - 请参阅子查询 t3