MySQL - 使用 LIMIT 更新查询

Posted

技术标签:

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

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

我尝试了以下查询:

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

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

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

【问题讨论】:

【参考方案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://***.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”

以上是关于MySQL - 使用 LIMIT 更新查询的主要内容,如果未能解决你的问题,请参考以下文章

05 MySQL之查询插入更新与删除

mysql update 语句如何更新多条数据

mysql update语句与limit的结合使用

更新异常。 Mysql sql不同的行影响计数

MySQL:更新视图在 MySQL 5.7 上失败,但在 5.6 上有效

mysql按条件分页查询的语句怎么写啊?