如何更新与另一行具有相同值的特定行?

时间:2013-01-30 15:08:58

标签: php mysql sql

我很难搞清楚这一个。我有这个数据库迟早会变大,看起来像这样。

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

3 个答案:

答案 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。