错误的更新限制了mysql

时间:2013-09-12 17:10:59

标签: php mysql

从这个问题:update multiple rows using limit in mysql?我为MySQL查询编写了这段代码:

UPDATE clientes SET telemarketer =1
WHERE telemarketer IN (
     SELECT telemarketer FROM (
         SELECT telemarketer FROM clientes 
         WHERE telemarketer=0
         ORDER BY telemarketer DESC
         LIMIT 0, 10
     ) temporal
 );

但它正在返回SELECT telemarketer FROM clientes

环顾四周,我发现案件中需要ORDER BY,否则会返回随机行。

为什么LIMIT没有工作?。

已经尝试使用LIMIT 10代替LIMIT 0, 10并获得相同的结果。

3 个答案:

答案 0 :(得分:4)

让我们从最里面的选择开始;

 SELECT telemarketer FROM clientes 
 WHERE telemarketer=0

...返回零行或多行0,因为这是唯一允许返回的值。 order by无关紧要,因为所有行都具有相同的值,并且该限制仅将零的数量限制为10。

这意味着您的整个查询;

UPDATE clientes SET telemarketer =1
WHERE telemarketer IN (
   SELECT telemarketer FROM (
      SELECT telemarketer FROM clientes 
      WHERE telemarketer=0
      ORDER BY telemarketer DESC
      LIMIT 0, 10
   ) temporal
);

......变成;

UPDATE clientes SET telemarketer =1
WHERE telemarketer IN (0, 0, ..., 0);

如果电话推销员为0的行数超过10行,则无论内部查询的限制如何,都会返回它们。

您可能需要使用唯一字段(主键?)来标识要更新的行;

UPDATE clientes SET telemarketer=1 
WHERE primary_key IN (
  SELECT primary_key FROM (
    SELECT primary_key FROM clientes WHERE telemarketer=0 LIMIT 10
  ) a
)

An SQLfiddle to test with

答案 1 :(得分:1)

尝试group_concat获取用于IN

的逗号分隔值
UPDATE clientes SET telemarketer =1
WHERE telemarketer IN (
     IFNULL(GROUP_CONCAT(
         SELECT c.telemarketer FROM clientes c 
         WHERE c.telemarketer=0
         ORDER BY c.telemarketer ASC
         LIMIT 10
     ),0) 
 );

在这里我们检查NULL值,如果有0行,那么我们用0替换它。

答案 2 :(得分:0)

问题在于你如何使用UPDATE中的子查询。来自http://dev.mysql.com/doc/refman/5.6/en/subquery-restrictions.html

  

通常,您无法修改表并从子查询中的同一个表中进行选择。

这意味着您无法在UPDATE语句中使用此类子查询。您需要做的是将其分成两个或多个语句,第一个用电话推销员列表构建临时表:

CREATE TEMPORARY TABLE temporal (telemarketer int);

INSERT INTO temporal
     SELECT telemarketer FROM clientes 
     WHERE telemarketer=0
     ORDER BY telemarketer DESC
     LIMIT 0, 10

然后您可以在更新中使用此表:

UPDATE clientes SET telemarketer =1
WHERE telemarketer IN (SELECT telemarketer FROM temporal);

DROP TABLE temporal;