55

我正在尝试插入一个新行并使用 max()+1 设置 customer_id。原因是该表已经在另一个名为 id 的列上有一个 auto_increatment,并且该表将有多个具有相同 customer_id 的行。

有了这个:

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  ((SELECT MAX( customer_id ) FROM customers) +1, 'jim', 'sock')

...我不断收到以下错误:

#1093 - You can't specify target table 'customers' for update in FROM clause

另外,我将如何阻止同时添加 2 个不同的客户并且没有相同的 customer_id?

4

11 回答 11

107

您可以使用该INSERT ... SELECT语句同时获取MAX()+1值和插入:

INSERT INTO 
customers( customer_id, firstname, surname )
SELECT MAX( customer_id ) + 1, 'jim', 'sock' FROM customers;

注意:您需要VALUES从您的中删除INSERT并确保SELECT所选字段与INSERT声明的字段匹配。

于 2011-03-19T04:48:54.050 回答
30

正确,您不能在同一查询中从同一表中修改和选择。您必须在两个单独的查询中执行上述操作。

最好的方法是使用事务,但如果您不使用 innodb 表,那么接下来最好锁定表,然后执行查询。所以:

Lock tables customers write;

$max = SELECT MAX( customer_id ) FROM customers;

获取最大 id 然后执行插入

INSERT INTO customers( customer_id, firstname, surname )
VALUES ($max+1 , 'jim', 'sock')

unlock tables;
于 2011-03-19T04:49:30.923 回答
15

像这样为内部查询使用别名

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  ((SELECT MAX( customer_id )+1 FROM customers cust), 'sharath', 'rock')
于 2016-04-25T05:37:31.153 回答
5

SELECT MAX(col) +1不安全——它不能确保您不会插入多个具有相同customer_id值的客户,无论是从同一张表还是从其他任何表中选择。确保在 MySQL 中插入表时分配唯一整数值​​的正确方法是使用 AUTO_INCREMENT 。ANSI 标准是使用序列,但 MySQL 不支持它们。AUTO_INCREMENT 列只能在 CREATE TABLE 语句中定义:

CREATE TABLE `customers` (
  `customer_id` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) DEFAULT NULL,
  `surname` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`customer_id`)
)

也就是说,这在 5.1.49 上对我来说效果很好:

CREATE TABLE `customers` (
  `customer_id` int(11) NOT NULL DEFAULT '0',
  `firstname` varchar(45) DEFAULT NULL,
  `surname` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$

INSERT INTO customers VALUES (1, 'a', 'b');

INSERT INTO customers 
SELECT MAX(customer_id) + 1, 'jim', 'sock'
  FROM CUSTOMERS;
于 2011-03-19T05:01:03.657 回答
5
insert into table1(id1) select (max(id1)+1) from table1;
于 2012-04-18T10:44:27.593 回答
5

在子查询中使用表别名:

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  ((SELECT MAX( customer_id ) FROM customers C) +1, 'jim', 'sock')
于 2014-10-02T23:35:15.490 回答
3

关于我的答案都不适用于我的情况。我从这里得到了答案,我的 SQL 是:

INSERT INTO product (id, catalog_id, status_id, name, measure_unit_id, description, create_time)
VALUES (
  (SELECT id FROM (SELECT COALESCE(MAX(id),0)+1 AS id FROM product) AS temp),
  (SELECT id FROM product_catalog WHERE name="AppSys1"),
  (SELECT id FROM product_status WHERE name ="active"),
  "prod_name_x",
  (SELECT id FROM measure_unit WHERE name ="unit"),
  "prod_description_y",
  UNIX_TIMESTAMP(NOW())
)
于 2017-11-13T10:15:37.760 回答
3

您的子查询不完整,仅此而已。请参阅下面的查询以及我的补充:

INSERT INTO customers ( customer_id, firstname, surname ) 
VALUES ((SELECT MAX( customer_id ) FROM customers) +1), 'jim', 'sock')
于 2019-09-09T16:27:21.657 回答
0

您不能在单个查询中执行此操作,但您可以在事务中执行此操作。执行初始 MAX() 选择并锁定表,然后执行插入。事务确保没有任何东西会中断这两个查询,而锁确保没有其他东西可以同时在别处尝试做同样的事情。

于 2011-03-19T04:45:44.303 回答
0

我们声明一个变量'a'

SET **@a** = (SELECT MAX( customer_id ) FROM customers) +1;

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  (**@a**, 'jim', 'sock')
于 2016-11-08T06:32:36.760 回答
0

这是选择来插入续集。

我正在尝试获取 serial_no 最大 +1 值及其给出正确值。

SELECT MAX(serial_no)+1 into @var FROM sample.kettle;
Insert into kettle(serial_no,name,age,salary) values (@var,'aaa',23,2000);
于 2019-04-03T05:41:21.547 回答