MySQL:使用Select和Limit更新行

时间:2014-12-29 15:17:01

标签: php mysql sql-update

我正在尝试将表中的所有行更新为基于LIMIT的for循环的迭代值,以便更新将分批完成。我从帖子update multiple rows using limit in mysql?中的建议中得到了启示,但它似乎给了我一个问题。该表有超过2400行,相关字段具有全0值。这是我的代码:

for($i = 0;$i < 7; $i++) {
    $qq2_ = $db1->prepare("UPDATE ledum_orgs SET ledum_org_size = :val WHERE ledum_org_size IN (
                            SELECT ledum_org_size FROM (
                                SELECT ledum_org_size FROM ledum_orgs WHERE ledum_org_size = '0'
                                ORDER BY ledum_org_name ASC
                                LIMIT ".($i*400).", 400
                            ) tmp
                          )"
                         );
    $qq2_->bindValue(':val',$i);
    $qq2_->execute();
    echo $i."=>".$qq2_->rowCount().", ";
}  

但它似乎忽略了LIMIT子句,将所有2445行的字段设置为'1'。这是输出:

0 =&gt; 0,1 =&gt; 2445,2 =&gt; 0,3 =&gt; 0,4 =&gt; 0,5 =&gt; 0,6 =&gt; 0,

有人可以告诉我为什么会出现这种行为吗?

1 个答案:

答案 0 :(得分:0)

在MySQL中,您不能在与limit一起使用的子查询中使用in。你也不能在子查询中引用正在更新的表(不使用join)。但是,您可以将其切换为join

UPDATE ledum_orgs lo JOIN
       (SELECT ledum_org_size
        FROM ledum_orgs
        WHERE ledum_org_size = '0'
        ORDER BY ledum_org_name ASC
        LIMIT ".($i*400).", 400
       ) tmp
       ON tmp.ledum_org_size = lo.ledum_org_size
    SET lo.ledum_org_size = :val;

您可以将其简化为:

UPDATE ledum_orgs lo
    SET lo.ledum_org_size = :val
    WHERE ledum_org_size = '0'
    ORDER BY ledum_org_name ASC
    LIMIT ".($i*400).", 400