I've the below mysql table where I want to update multiple rows of approval_status
field with 1
if the quantity passed is more than the qty_req
value using MySql or PHP.
Requisition 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 |
Example:
$update_status=Array (
[0] => Array ( [part_id] => 17 [qty] => 90 )
[1] => Array ( [part_id] => 16 [qty] => 70 )
)
From the above array, 90
is the quantity available for the part_id
17
. I want to update the approval_status
as 1
in the requisition
table for the rows with the part_id
as 17 with the below scenario:
Update the approval_status
to 1
as the quantity of the first row with part_id
17 is 30 which is less than 90.
Update the approval_status
to 1
as the quantity of the second row with part_id
17 is 30+50=80
which is less than 90.
Third row won't update as the total 30+50+60=140
is greater than 90.
Unfortunately, I couldn't find any tutorial to achieve this.
Any help would be appreciated. Thanks in advance.
Single data:
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;
Multiple data:
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
Column reg_date
and unique index added for to provide definite and unambiguous rows ordering.
The solution applicable to MySQL 5.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
Source data must be formed as a query text - see subquery t3
.