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

时间:2016-05-30 13:34:02

标签: mysql sql select sql-update auto-increment

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

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

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

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

  

错误:重复输入' 2'对于关键' slides_position_unique'

如何在不引起冲突的情况下更新所有这些唯一号码?我已经尝试了一个查询所有可更新行的子查询并反过来返回它们,但它没有帮助。

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

3 个答案:

答案 0 :(得分:3)

问题在于唯一约束 - 在更新期间,值不是唯一的。您可以在事务中执行此操作或删除约束,然后添加它:

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/66e0d8

答案 1 :(得分:3)

您可以在更新中使用订单。作为mysql doc事实:

  

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

这将导致:

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

这样你更新了更大的第一个,然后是更大的-1,然后是更大的2,等等...并且唯一的索引在被分配到下一行之前总是被释放。

答案 2 :(得分:0)

错误很明显:应用此查询会产生重复的行。为了避免更改您的查询。我想这意味着要么删除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但这可能会让您丢失一些行。