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

i7uq4tfw  于 11个月前  发布在  Mysql
关注(0)|答案(3)|浏览(129)

我试图更新一个包含两列的表; idpositionid是唯一的,并自动递增。position是唯一的,但不自动递增,实际上必须手动设置。
我需要修改所有位置大于或等于5(或我提供的任何其他数字)的行,以将它们全部递增1。这是我的代码:

UPDATE slides 
SET   position = position + 1 
WHERE position >= 5;

字符串
不幸的是,它返回以下错误:
错误:关键字'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) )

kd3sttzy

kd3sttzy1#

您可以在update中使用order by。作为mysql doc事实:
如果指定了ORDERBY子句,则按指定的顺序更新行
这将导致:

UPDATE slides 
SET   position = position + 1 
WHERE position >= 5
ORDER BY position DESC;

字符串
这样你就可以先更新greater,然后是greater-1,然后是greater-2,等等,唯一索引总是在分配给下一行之前被释放。
请注意,根据您的用例,如果其他脚本需要同时访问此数据,您可能希望使用row或table locking来避免竞争条件。

46scxncf

46scxncf2#

问题出在唯一约束上--在更新过程中,值不是唯一的。你可以在transaction中完成,或者删除约束,然后添加它:

ALTER TABLE slides DROP index slides_position_unique;
UPDATE slides SET position = position + 1 WHERE position >= 1;
ALTER TABLE slides ADD CONSTRAINT  slides_position_unique UNIQUE (position);

字符串
有关工作示例,请参见http://sqlfiddle.com#!9/66 e0 d8。

irtuqstp

irtuqstp3#

这个错误很明显:应用此查询会产生重复的行。为了避免这种情况,请更改您的查询。我认为这意味着要么删除WHERE position >= 1(更新所有行),要么添加另一个条件以排除slides.position < 1
也许这个更简单的查询对你有用:

UPDATE slides 
SET   position = position + 1 
WHERE position >= 1 AND position IS NOT NULL

字符串
您可能会使用UPDATE IGNORE slides set position = position+1,但这可能会使您失去一些行。

相关问题