【问题标题】:How to use SELECT MAX inside an INSERT statement in MySQL?如何在 MySQL 的 INSERT 语句中使用 SELECT MAX?
【发布时间】:2019-02-14 07:54:30
【问题描述】:

短版: 使用 INSERT INTO 语句添加行时,如何获取列的最大值并使用结果?

加长版: 我已阅读问题:How to use 'select ' in MySQL 'insert' statement 并尝试按照说明进行回答。这是我的查询:

INSERT INTO employee (id, name, state, supervisorId) SELECT MAX(id)+1, 'Dan', state, supervisorId FROM employee WHERE name='Chris';

但我收到此错误:

ERROR: 1062: Duplicate entry '7' for key 'PRIMARY'

原因是我有另一行 id 为 7。因此,

MAX(id)

不返回实际的最大值,而是一个等于包含 'Chris' 的行的 id 的值,即 6。

我做错了什么?

【问题讨论】:

  • “我做错了什么?”不要这样做,你的想法看起来很容易出现 竞争条件。如果两个插入同时发生,两个 id 可以是相同的。除了你在重新发明轮子 MySQL 有AUTO_INCREMENT为此(dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html
  • @RaymondNijland 我对mySQL了解不多,但我认为应该存在排他锁机制,不是吗?
  • "我对 mySQL 了解不多,但我认为应该存在排他锁机制,不是吗" 是的,但是为什么要锁定会降低 InnoDB 引擎上的线程并发性的表? @BarbarosÖzhan 我在这里假设 InnoDB,因为 InnoDB 是 MySQL 中的默认表引擎几年了。
  • 感谢@RaymondNijland,但我尝试运行此命令“INSERT INTO employee (name, state, supervisorId) SELECT 'Dan', state, supervisorId FROM employee WHERE name='Chris';”但它给了我这个错误:“错误:1364:字段'id'没有默认值”
  • 运行 ALTER TABLE employee MODIFY COLUMN id INT AUTO_INCREMENT 然后您的 INSERT 应该可以正常工作。

标签: mysql sql select max insert-into


【解决方案1】:

您可以通过替换它来修复它:

MAX(id)+1

使用此选择查询:

(SELECT MAX(id)+1 FROM employee)

这是完整的查询:

INSERT INTO employee (id, name, state, supervisorId) SELECT (SELECT MAX(id)+1 FROM employee), 'Dan', state, supervisorId FROM employee WHERE name='Chris';

更新:

虽然这个答案解决了关于在 INSERT 查询中获取 SELECT MAX 的一般问题,正如@RaymondNijland 建议的那样,但最好充分利用 MySQL auto_increment 功能。这样做:

1) 使您的主键列自动递增:

 ALTER TABLE employee MODIFY COLUMN id INT NOT NULL AUTO_INCREMENT;

2) 从插入查询中删除 id:

INSERT INTO employee (name, state, supervisorId) SELECT 'Dan', state, supervisorId FROM employee WHERE name='Chris';

【讨论】:

  • 这看起来很容易出现竞态条件。如果两个插入同时发生会怎样???
  • 请注意,您应该使用AUTO_INCREMENT,就像我评论的那样,由于可能的竞态条件 @ComputerLover,这可能会导致非常讨厌的调试问题
  • @ComputerLover 虽然您可以使用我的答案在插入查询中获取 MAX 以增加 id,但我强烈建议您了解更多有关如何充分利用 Raymond 建议的 auto_increment 的信息。
【解决方案2】:

对 SQL 查询使用手动增量可能会导致竞争条件。 创建表 PK(主键)时应该有 AI(自动增量)约束。

    CREATE TABLE table_name
    (
    table_id int NOT NULL PRIMARY KEY AUTO INCREMENT,
    ....
    );

如果您绝对必须使用手动增量,请使用 SELECT 语句。

【讨论】:

  • 谢谢@rusito23,这就是Raymond 和Navid 所说的。我同意在这种情况下使用 auto_increment 更有意义,但我想知道如何使该查询工作,即使它不是自动增量。
猜你喜欢
  • 2012-06-15
  • 2011-12-04
  • 2019-09-14
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
相关资源
最近更新 更多