我很难搞清楚这一个。我有这个数据库迟早会变大,看起来像这样。
est_id |mat_id | est_qty | qty_rec
2 | 29 | 50 | 0
3 | 29 | 70 | 0
8 | 29 | 100 | 0
现在,我想要完成的是更新单行,直到est_qty和qty_rec相等,然后移到另一行。我开始编写代码,但它没有用。
foreach($mat_id as $mat_id_key => $mat){
while($rec_qty > 0){
$remBal = $est_qty[$mat_id_key] - $qty_rec[$mat_id_key];
if(($remBal - $rec_qty) >= 0){
mysql_query('UPDATE `estimates` SET `qty_rec` = `qty_rec` + '.$rec_qty.' WHERE `proj_id` = "'.$proj_id.'" AND `mat_id` = "'.$mat[$mat_id_key].'"');
}
}
}
在这段代码中,每一行都将进入循环,直到它满足条件,即est_qty和$rec_qty
之间的差值大于或等于零,它将更新该行。
例如,用户输入30作为$rec_qty
,数据库现在看起来像:
est_id |mat_id | est_qty | qty_rec
2 | 29 | 50 | 30
3 | 29 | 70 | 0
8 | 29 | 100 | 0
当用户第二次输入时,例如40为$rec_qty
时,数据库现在看起来像:
est_id |mat_id | est_qty | qty_rec
2 | 29 | 50 | 50
3 | 29 | 70 | 20
8 | 29 | 100 | 0
答案 0 :(得分:1)
这是一个基于集合的单个查询来执行此操作,但它使用triangular-join:
update est as e
join (
select *
, case when needed - room_below > room then room else needed - room_below end as to_add
from (
select *
, est_qty - qty_rec as room
, (select coalesce(sum(est_qty - qty_rec), 0) from est where mat_id = a.mat_id and est_id < a.est_id) as room_below
, 30 as needed -- Variable?
from est as a
) as b
) as c on e.est_id = c.est_id
set e.qty_rec = e.qty_rec + c.to_add
where e.mat_id = 29 -- Variable?
and c.to_add > 0;
应该注意的是,这没有处理溢出条件的逻辑,你试图插入一个比现有记录更大的数字(你可能需要插入一个新记录来保存)其余的)。
有一个SqlFiddle演示here。
答案 1 :(得分:0)
由于您的表没有唯一ID,因此您的UPDATE将更新与proj_id和mat_id匹配的所有行。因此,如果您从:
开始mat_id | est_qty | qty_rec
29 | 50 | 30
29 | 70 | 0
29 | 100 | 0
并添加40,您最终会得到:
mat_id | est_qty | qty_rec
29 | 50 | 70
29 | 70 | 70
29 | 100 | 70
甚至:
mat_id | est_qty | qty_rec
29 | 50 | 40
29 | 70 | 40
29 | 100 | 40
...取决于首先找到哪一行。
向表中添加主键,然后根据此ID更新记录。
答案 2 :(得分:0)
你不需要循环。这两个查询就足够了:
mysql_query("set @remain := $rec_qty");
mysql_query(
"update estimates
set qty_rec = @remain,
qty_rec = qty_rec - (@remain := if( qty_rec > est_qty, qty_rec - est_qty, 0)
where mat_id = $matId
order by est_id"
);
$ matId是您要更新的mat_id。