在一个查询中的每一行中增加唯一列

For*_*est 0 mysql sql select auto-increment sql-update

我正在尝试更新包含两列的表;idpositionid是唯一的并且自动递增。position是唯一的,但不会自动递增,实际上必须手动设置。

我需要更改位置大于或等于5(或我提供的任何其他数字)的所有行,以将它们全部加一。这是我的代码:

UPDATE slides 
SET   position = position + 1 
WHERE position >= 5;
Run Code Online (Sandbox Code Playgroud)

不幸的是,它返回以下错误:

错误:键“slides_position_unique”的条目“2”重复

如何更新所有这些唯一编号而不引起冲突?我尝试过一个子查询来查找所有可更新的行并反向返回它们,但它没有帮助。


CREATE TABLE slides
  (id int(10) unsigned NOT NULL AUTO_INCREMENT,
   user_id int(10) unsigned NOT NULL,
   position int(10) unsigned NOT NULL,
   PRIMARY KEY (id),
   UNIQUE KEY slides_position_unique (position),
   KEY slides_user_id_foreign (user_id),
   CONSTRAINT slides_user_id_foreign
     FOREIGN KEY (user_id) REFERENCES users (id) )
Run Code Online (Sandbox Code Playgroud)

Sou*_*zal 5

您可以在更新中使用 order by 。正如mysql 文档事实:

如果指定了 ORDER BY 子句,则按指定的顺序更新行

这将导致:

UPDATE slides 
SET   position = position + 1 
WHERE position >= 5
ORDER BY position DESC;
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以先更新更大的值,然后更新更大的 1,然后更新更大的 2,等等...并且唯一索引在分配给下一行之前始终会被释放。

请注意,根据您的用例,如果其他脚本需要同时访问此数据,您可能需要使用行锁定或表锁定来避免竞争条件。

  • 完全相同的问题;这就是解决方案——谢谢!人们应该对此表示赞同,OP 应该接受它是正确的 (2认同)