MySQL-带LIMIT的UPDATE查询


75

我想将表中的行从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. 要做到这一点怎么办?

Answers:


29

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

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

LIMIT可以与UPDATErow count只能一起使用


感谢您的答复。您能给我一个为什么IS NULL与= null不同的见解。也。IS NULL到底能找到什么空值?
拉胡尔·谢尔克

2
@ srahul07:因为NULL不是真实值,所以=请检查两个值是否相等。因此=不匹配null。
Shakti Singh

@Framework,更新限制,row count不适用于mysql版本5.1.X
Pragnesh Chauhan,

130

如果要使用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
)

23
MySQL 5.5在IN / ALL / ANY / SOME子查询中不支持LIMIT:错误代码1235
FiveO 2014年

9
@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',但是如果我同时包含两个选择,则查询有效。
Mark Amery 2014年

2
顺便说一下,对于Postgres 9.4,这种代码无需外部SELECT id FROM (…就可以工作) tmp 。谢谢。似乎应该是“已接受的答案”。
罗勒·布尔克

11

我建议两步查询

我假设您有一个自动递增的主键,因为您说您的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。


8

除了上面的嵌套方法,您还可以在同一张表上完成LIMITusing的应用JOIN

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

以我的经验,mysql查询优化器更适合这种结构。


4
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)


2
您假设他在表上有一个auto_increment,但事实并非如此,也不必是连续的数字序列。
jishi

好吧,是的,当然,我正在做这个假设,我将以此来更新答案,等待更多信息!:)
Nicola Peluchetti 2011年

感谢您的回应。实际上,主键是MAX + 1。
拉胡尔·谢尔克

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查询将非常完美!
deepcell

4

您可以使用LIMIT来实现,而不能使用LIMIT和OFFSET来实现。


1

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

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

LIMITMySQL中的子句应用于更新时,不允许指定偏移量。


这在类似但不同的情况下对我有所帮助-查询应读取“更新my_table设置process_id = n限制1000”而不是“更新my_table设置process_id = n限制0,1000”
rrrhys 2013年

0

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

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


0

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

由于官方文件状态

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

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

更新客户SET countryCode ='USA'WHERE country ='USA'; -这给出了错误,您只需编写:

更新客户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);

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.