【问题标题】:MySQL - UPDATE query with LIMITMySQL - 使用 LIMIT 更新查询
【发布时间】:2011-09-11 11:53:46
【问题描述】:

我想更新表中从 1001 到下一个 1000 的行。

我尝试了以下查询:

UPDATE `oltp_db`.`users` SET p_id = 3 LIMIT 1001, 1000
  1. 这给了我语法错误。它是否正确?我在这里做错了吗?
  2. 我们可以这样限制更新吗?

此外,我尝试更新的行对于数据类型为 INTEGER 的列 p_id 具有 Null 值。因此,我什至无法使用以下查询进行更新:

UPDATE `oltp_db`.`users` SET p_id = 3 WHERE p_id = null
  1. 我上面的查询是否正确?
  2. 可以做些什么来实现这一目标?

【问题讨论】:

    标签: mysql limit sql-update


    【解决方案1】:

    除了上面的嵌套方式,还可以在同一张表上使用JOIN完成LIMIT的应用:

    UPDATE `table_name`
    INNER JOIN (SELECT `id` from `table_name` order by `id` limit 0,100) as t2 using (`id`)
    SET `name` = 'test'
    

    根据我的经验,mysql 查询优化器更喜欢这种结构。

    【讨论】:

      【解决方案2】:

      对于人们通过搜索“更新限制 MySQL”来获得这篇文章,试图避免在使用多表语法面对 update 时关闭 safe update mode

      the offical document状态

      对于多表语法,UPDATE 更新每个名为的表中的行 在满足条件的 table_references 中。在这种情况下,订购 不能使用 BY 和 LIMIT。

      https://stackoverflow.com/a/28316067/1278112
      我认为这个答案很有帮助。举个例子

      更新客户 SET countryCode = 'USA' WHERE国家='美国'; -- 这给出了错误,你只需写:

      更新客户 SET countryCode = 'USA' WHERE (country = 'USA' AND customerNumber 0); -- 因为 customerNumber 是主键,所以不再出现错误 1175。

      我想要但会引发错误代码 1175。

      UPDATE table1 t1
              INNER JOIN
          table2 t2 ON t1.name = t2.name 
      SET 
          t1.column = t2.column
      WHERE
          t1.name = t2.name;
      

      工作版

      UPDATE table1 t1
              INNER JOIN
          table2 t2 ON t1.name = t2.name 
      SET 
          t1.column = t2.column
      WHERE
          (t1.name = t2.name and t1.prime_key !=0);
      

      这真的很简单和优雅。由于原始答案没有得到太多关注(投票),因此我发布了更多解释。希望这可以帮助其他人。

      【讨论】:

        【解决方案3】:

        在处理 null 时,= 不匹配 null 值。您可以使用IS NULLIS NOT NULL

        UPDATE `smartmeter_usage`.`users_reporting` 
        SET panel_id = 3 WHERE panel_id IS NULL
        

        LIMIT 可以与UPDATE 一起使用,但只能与row count 一起使用

        【讨论】:

        • 感谢您的回复。您能否告诉我为什么 IS NULL 与 = null 不同。还。 IS NULL 究竟是做什么来查找空值的?
        • @srahul07:因为 NULL 不是真实值,= 检查两个值是否相等。因此= 不匹配 null。
        • @Framework,row count 的更新限制不适用于 mysql 版本 5.1.X
        【解决方案4】:

        您可以使用 LIMIT 来做到这一点,但不能使用 LIMIT 和 OFFSET。

        【讨论】:

          【解决方案5】:

          如果你想在 MySQL 中使用 limit 更新多行,你可以使用这个构造:

          UPDATE table_name SET name='test'
          WHERE id IN (
              SELECT id FROM (
                  SELECT id FROM table_name 
                  ORDER BY id ASC  
                  LIMIT 0, 10
              ) tmp
          )
          

          【讨论】:

          • MySQL 5.5 不支持 IN/ALL/ANY/SOME 子查询中的 LIMIT:错误代码 1235
          • @FiveO 在 MySQL 5.5.34 上运行良好。如果没有嵌套子查询(不正当的SELECT id FROM (SELECT id FROM ...) 构造),我会得到ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery',但如果我同时包含两个选择,如此处所示,则查询有效。
          • 顺便说一下,对于 Postgres 9.4,这种代码不需要外部的 SELECT id FROM ( ... ) tmp 。谢谢。似乎这应该是接受的答案。
          • 是的,限制不适用于更新。为你 +1,伙计 :)
          【解决方案6】:

          我建议两步查询

          我假设您有一个自动递增主键,因为您说您的 PK 是 (max+1),这听起来像是自动递增键的定义。
          我打电话给 PK id,用你的 PK 代替。

          1 - 找出第 1000 列的主键号。

          SELECT @id:= id FROM smartmeter_usage LIMIT 1 OFFSET 1000
          

          2 - 更新表格。

          UPDATE smartmeter_usage.users_reporting SET panel_id = 3 
          WHERE panel_id IS NULL AND id >= @id 
          ORDER BY id 
          LIMIT 1000
          

          请测试一下我是否没有犯过一个错误;您可能需要在某处加或减 1。

          【讨论】:

            【解决方案7】:
            UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 LIMIT 1001, 1000
            

            这个查询不正确(或者至少我不知道在 UPDATE 查询中使用限制的可能方法),你应该在你的主键上放置一个 where 条件(这假设你有一个 auto_increment 列作为你的主键,如果没有提供更多详细信息):

            UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 WHERE primary_key BETWEEN 1001 AND 2000
            

            对于第二个查询,您必须使用 IS

            UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 WHERE panel_id is null
            

            编辑 - 如果您的 primary_key 是一个名为 MAX+1 的列,则您的查询应该是(注释中正确说明的反引号):

            UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 WHERE `MAX+1` BETWEEN 1001 AND 2000
            

            将 MAX+1 的行从 1001 更新到 2000(包括 1001 和 2000)

            【讨论】:

            • 您假设他的桌子上有一个 auto_increment,但事实可能并非如此,也不一定是连续的数字序列。
            • 嗯,是的,我当然在做这个假设,我会用这个来更新答案,等待更多信息! :)
            • 感谢您的回复。实际上主键是 MAX+1。
            • -1, (A) max 是保留字,需要用反引号引起来。 (B) max + 1 between 1001 and 2000 应改写为 max between 1000 and 1999。 (C) 我从未听说过没有意义的名为max+1 的主键。 (D) 此代码假定列max 是连续的,这不能以任何方式保证。 (E) 限制适用于update
            • 很好的答案。如果您有 PK 自动增量,您的第一个 UPDATE 查询就可以完美运行!
            【解决方案8】:

            如果您打算限制更新,则应高度考虑使用ORDER BY,否则它将按照表的顺序进行更新,这可能不正确。

            但正如 Will A 所说,它只允许对 row_count 进行限制,而不是偏移量。

            【讨论】:

              【解决方案9】:

              您应该使用 IS 而不是 = 来与 NULL 进行比较。

              UPDATE `smartmeter_usage`.`users_reporting`
              SET panel_id = 3
              WHERE panel_id IS null
              

              MySQL 中的LIMIT 子句在应用于更新时不允许指定偏移量。

              【讨论】:

              • 这在类似但不同的情况下帮助了我 - 查询应该是“update my_table set process_id = n limit 1000”而不是“update my_table set process_id = n limit 0,1000”
              猜你喜欢
              • 1970-01-01
              • 2020-11-24
              • 1970-01-01
              • 2012-05-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-03
              相关资源
              最近更新 更多