Insert and set value with max()+1 problems

杀马特。学长 韩版系。学妹 提交于 2019-12-17 15:39:22

问题


I am trying to insert a new row and set the customer_id with max()+1. The reason for this is the table already has a auto_increatment on another column named id and the table will have multiple rows with the same customer_id.

With this:

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

...I keep getting the following error:

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

Also how would I stop 2 different customers being added at the same time and not having the same customer_id?


回答1:


Correct, you can not modify and select from the same table in the same query. You would have to perform the above in two separate queries.

The best way is to use a transaction but if your not using innodb tables then next best is locking the tables and then performing your queries. So:

Lock tables customers write;

$max = SELECT MAX( customer_id ) FROM customers;

Grab the max id and then perform the insert

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

unlock tables;



回答2:


You can use the INSERT ... SELECT statement to get the MAX()+1 value and insert at the same time:

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

Note: You need to drop the VALUES from your INSERT and make sure the SELECT selected fields match the INSERT declared fields.




回答3:


Use alias name for the inner query like this

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  ((SELECT MAX( customer_id )+1 FROM customers cust), 'sharath', 'rock')



回答4:


SELECT MAX(col) +1 is not safe -- it does not ensure that you aren't inserting more than one customer with the same customer_id value, regardless if selecting from the same table or any others. The proper way to ensure a unique integer value is assigned on insertion into your table in MySQL is to use AUTO_INCREMENT. The ANSI standard is to use sequences, but MySQL doesn't support them. An AUTO_INCREMENT column can only be defined in the CREATE TABLE statement:

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

That said, this worked fine for me on 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;



回答5:


insert into table1(id1) select (max(id1)+1) from table1;



回答6:


Use table alias in subquery:

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



回答7:


None of the about answers works for my case. I got the answer from here, and my SQL is:

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



回答8:


You can't do it in a single query, but you could do it within a transaction. Do the initial MAX() select and lock the table, then do the insert. The transaction ensures that nothing will interrupt the two queries, and the lock ensures that nothing else can try doing the same thing elsewhere at the same time.




回答9:


We declare a variable 'a'

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

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  (**@a**, 'jim', 'sock')



回答10:


Mine is an insert, but here is what I ended up with using the suggestions here.

update
   m
set
   m.host_id = max(h.host_id)
from
   t_po_master as m
   inner join t_al_host_po_master as h on m.po_number = h.po_number
where
   m.host_id is NULL
   and m.client_code = '01'

EDIT - This actually didn't work. I'm not certain why not since turning it into a select statement appears that it would work, but this updated all the host_ids to the same id. So I wouldn't use this is a good example.




回答11:


This is select come insert sequel.

I am trying to get serial_no maximum +1 value and its giving correct value.

SELECT MAX(serial_no)+1 into @var FROM sample.kettle;
Insert into kettle(serial_no,name,age,salary) values (@var,'aaa',23,2000);



回答12:


Your sub-query is just incomplete, that's all. See the query below with my addictions:

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


来源:https://stackoverflow.com/questions/5360117/insert-and-set-value-with-max1-problems

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!