How to use SELECT MAX inside an INSERT statement in MySQL? - mysql

Short Version:
How can I get the maximum value of a column and use the result when adding a row with INSERT INTO statement?
Long Version:
I have read the question: How to use 'select ' in MySQL 'insert' statement and tried to follow the instructions for its answers. This is my query:
INSERT INTO employee (id, name, state, supervisorId) SELECT MAX(id)+1, 'Dan', state, supervisorId FROM employee WHERE name='Chris';
But I get this error:
ERROR: 1062: Duplicate entry '7' for key 'PRIMARY'
The reason is that I have another row whose id is 7. Consequently,
MAX(id)
doesn't return the actual maximum value, but a value equal to id of the row containing 'Chris' which is 6.
What am I doing wrong?

You can fix it by replacing this:
MAX(id)+1
with this select query:
(SELECT MAX(id)+1 FROM employee)
Here's the complete query:
INSERT INTO employee (id, name, state, supervisorId) SELECT (SELECT MAX(id)+1 FROM employee), 'Dan', state, supervisorId FROM employee WHERE name='Chris';
Update:
Although this answer solves the general question about getting the SELECT MAX inside an INSERT query, as #RaymondNijland suggested, it's better to make the most of MySQL auto_increment functionalities. To do so:
1) Make your primary key column, auto incremented:
ALTER TABLE employee MODIFY COLUMN id INT NOT NULL AUTO_INCREMENT;
2) Remove the id from your insert query:
INSERT INTO employee (name, state, supervisorId) SELECT 'Dan', state, supervisorId FROM employee WHERE name='Chris';

Using manual increment on SQL queries can lead to race conditions.
You should have the AI (auto increment) constraint when you create your table PK (Primary Key).
CREATE TABLE table_name
(
table_id int NOT NULL PRIMARY KEY AUTO INCREMENT,
....
);
If you absolutely have to use manual increment, use SELECT statement.

Related

Max of a coll in my sql

I want to make a register system, to record some values from html inputs in a Database, I use the following query:INSERT INTO Search (id, username, fname, lname, age, fullname) VALUES ('?', '$username', '$fname', '$lname', '$age', '$fullname');
But I don't know how to increment the id every time when submit a name:
see here
I want something like:
id
""""""""""""""""
1
max+1
new max+1
You don't; you make it an auto increment column ( https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html ) and then you don't specify it in the insert statement, and mysql will calculate the next value to put in automatically
When creating your table, you should specify the id column to AUTO_INCREMENT like so:
id INTEGER NOT NULL AUTO_INCREMENT
you can alter your table at this point.
You should definitely not do this by hand IMO.
You should also consider declaring it a PRIMARY KEY.
Run the following:
ALTER TABLE Search
CHANGE COLUMN id id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (id);
or execute two queries:
SET #max = 0;
INSERT INTO Search
(id, username, fname, lname, age, fullname)
VALUES
(#max:=#max+1, '$username', '$fname', '$lname', '$age', '$fullname');

insert a new record into a mysql table with one of the values incremented by 1

I've got the following table:
productId price
1 price_value1
2 price_value2
3 price_value3
I would like to insert a new product into the table and assign it a new productId. In this case its value equals to 4.
So I want my new table to look like so:
productId price
1 price_value1
2 price_value2
3 price_value3
4 price_value4
So as far as I understand, in order to do that I have to somehow retrieve the max value of productId and insert it using INSERT INTO mytable VALUES (productId + 1, price_value4).
But how do I find out the maximum value of productId?
I tried INSERT INTO mytable VALUES (SELECT MAX(productId) + 1 FROM mytable, price_value4) but it didn't work.
This should Work:
Select the max(productID) and price_value4 as a columns from mytable and insert the result.
INSERT INTO mytable (SELECT MAX(productId) + 1, 'price_value4' FROM mytable);
However, if you are not going to jump some number you can just add an auto increment id key to product_id and then you will have only to insert the price, the product ID will be incremented automatically..
This will do so :
ALTER TABLE mytable
MODIFY COLUMN `productId` INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT;
you can change INT(10) with the INT(5) for example depanding on the size you want to give to your productId column
EDIT :
In return to the OP question in comments why his solution wouldn't work
Some suggetions says you have to make the SELECT statment in insert always between parenthesis
INSERT INTO mytable VALUES ( (SELECT MAX(ID)+1 FROM mytable) , price_value4)
.. In my Case it Return
(1093): You can't specify target table
'mytable' for update in FROM clause
AND HERE IS WHY (Quoting From the documentation)
When selecting from and inserting into the same table, MySQL creates
an internal temporary table to hold the rows from the SELECT and then
inserts those rows into the target table. However, you cannot use
INSERT INTO t ... SELECT ... FROM t when t is a TEMPORARY table,
because TEMPORARY tables cannot be referred to twice in the same
statement
BUT there is away to overcome by using a query instead of the table itself in the FROM, which has the effect of copying the requested table values instead of referencing the one that you are updating..
INSERT INTO mytable VALUES (
(SELECT MAX(ID)+1 FROM (SELECT * FROM mytable ) as mytmp ),
'price_value4');
OR (Quoting From the documentation)
To avoid ambiguous column reference problems when the SELECT and the
INSERT refer to the same table, provide a unique alias for each table
used in the SELECT part, and qualify column names in that part with
the appropriate alias.
INSERT INTO mytable Values ( (SELECT MAX(ID)+1 FROM mytable as mytmp) , 'price_value4')
This is a duplicate question. In order to take advantage of the auto-incrementing capability of the column, do not supply a value for that column when inserting rows.
A simple syntax to create table
CREATE TABLE Product (
productId MEDIUMINT NOT NULL AUTO_INCREMENT,
price INT NOT NULL,
PRIMARY KEY (productid)
);
While inserting supplied default or leave column as blank or supplied value as NULL. Take a look at below code snippet.
INSERT INTO Product (price) VALUES
('10'),('20'),('4'),
('30');
refer this link

SQL Insert from table to table prevented by duplicate primary key from source table

I am trying to populate a products table on MySQL with latest products, which are retrieved and stored in products_temp table.
So the method for this is straight forward, simply doing an INSERT to products from products_temp, as such:
INSERT INTO products ( select products_temp.* FROM products_temp )
Problem is, it results in a duplicate primary key error, because of the id from products_temp clashing with the id in products.
Can someone tell me how to fix this please?
I tried declaring the fields in the select statement without the id, but that results in "Column count doesn't match value count at row 1"
Any help would be appreciated.
Thanks!
You'll need to declare the columns except the ID on both the INSERT and the SELECT, since the number of fields need to match, and id (as you noticed) can't be inserted as is into the destination table.
INSERT INTO DestTable (field1, field2, field3)
SELECT field1, field2, field3 FROM SourceTable;
An SQLfiddle to test with.
EDIT: You could do it in a bit more hacky way to simplify the insert. You can create a trigger that simply forces the primary key to NULL on insert.
CREATE TRIGGER t_DT BEFORE INSERT ON DestTable
FOR EACH ROW
SET NEW.id = NULL;
then a copy from table to table can be done as simply;
INSERT INTO DestTable SELECT * FROM SourceTable;
Another SQLfiddle.
How about something like:
INSERT INTO products
(
select products_temp.* FROM products_temp
where key not in (select key from products)
)

Single query for "INSERT INTO table if column value not found"

How can I use a single query for inserting table when a column value is not found.
eg/ i want to insert new user only when this username not found
what i doing now is issue 1 query to check for existing,
then another query if no existing found. total 2 query
INSERT INTO friends (memberID) SELECT 1 WHERE NOT EXISTS (SELECT memberID FROM friends WHERE memberID = 1)
You just need to add FROM DUAL
INSERT INTO friends
(memberid)
SELECT 1
FROM dual
WHERE NOT EXISTS (SELECT memberid
FROM friends
WHERE memberid = 1)
sql fiddle
How about this:
INSERT INTO YourTable (UserName)
SELECT x
FROM (SELECT 'New User Name' AS x) a
WHERE x NOT IN(SELECT UserName
FROM YourTable)
Since you only want one row with a given value you should enforce that with a UNIQUE constraint on the table, for example:
ALTER TABLE friends ADD UNIQUE (memberID);
After you do that, you can simply add the IGNORE keyword to your insert statements and it won't report an error and it won't insert a duplicate row if it already exists.
INSERT IGNORE INTO friends(memberID) VALUES(1);

With MySQL, how do I insert into a table on condition that the value does not exist in same table?

insert into student (FirstName,AGE,CITYID) values('guna','26','1')
select * from student WHERE FirstName!='guna';
This query showing error.I can't make FirstName column as unique. Please give an idea other than this.
Thanks
INSERT INTO student ( ....)
WHERE FirstName NOT IN (SELECT FirstName FROM student)
After revision and testing:
INSERT INTO student
(FirstName, age, cityid)
SELECT
'guna','26','1'
FROM student -- any table name will do
WHERE 'guna' NOT IN
(
SELECT FirstName
FROM student
)
LIMIT 1 -- required because all rows will qualify if
-- WHERE clause is satisfied
You can add a unique index on that table which will do the same for you
ALTER TABLE student ADD UNIQUE <name_of_index>[optional] (FirstName);
EDIT:
If you cant use a unique index..
One soln i can think of is using compound statements - http://dev.mysql.com/doc/refman/5.0/en/if-statement.html