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 NULL
或IS 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 更新查询的主要内容,如果未能解决你的问题,请参考以下文章