【问题标题】:Increment a unique column in every row in one query在一个查询的每一行中增加一个唯一列
【发布时间】:2016-09-28 08:44:00
【问题描述】:

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

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

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

【问题讨论】:

  • show create table slides` 的输出是什么?
  • 不要将其他信息放入 cmets - 相反,编辑您的问题并将新信息添加到问题中。这次我已经为你做了。今后请牢记这一点。谢谢。

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


【解决方案1】:

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

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

这将导致:

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

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

【讨论】:

  • 完全相同的问题;这是解决方案-谢谢!人们应该对此表示赞同,OP 应该接受它是正确的
【解决方案2】:

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

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

【讨论】:

  • 耶稣。这是一个很好的观点,完全有可能告诉我做奇怪嵌套的人实际上是错误的。
  • 查看 CREATE 语句,我发现您对位置有 UNIQUE 约束。我认为 UPDATE 将在位置列中创建重复项。检查此 SQL Fiddle:sqlfiddle.com#!9/fe46ee/1,您可以看到更新在简单输入数据上按预期工作。
  • 您是否建议删除唯一标志并简单地确保它在软件中是唯一的?
  • 我认为最好在更新前将其删除,然后在更新后立即添加。我认为如果日期在更新之前是一致的,它们也会在更新之后 - 问题是在更新期间,有一些重复的值。
  • 在没有它的情况下测试了代码,它似乎可以正常工作。不过,我想在更新时我需要锁定表才能写入,因为如果它被中断会很混乱。
【解决方案3】:

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

【讨论】:

  • 这会返回相同的错误。我还尝试尝试删除WHERE position >= 1,但无济于事。
  • 所以您的某些数据可能无效。职位类型 = intnull 是否被禁止?我刚刚编辑了我的答案以排除无效位置。否则,如果您可能会丢失一些不连贯的数据,您可以尝试update ignore
  • Null 是禁止的,是的。只是int。我对这个问题很困惑。
猜你喜欢
  • 2018-02-07
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 2013-01-31
  • 2010-10-10
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多