Retrieving all LAST_INSERT_ID of MySQL batch INSERT ... ON DUPLICATE UPDATE ...? - mysql

Current rows in t1:
id,f1,f2,f3
1,'01','02','03'
2,'11','12','13'
4,'41','42','43'
Wherein f1 is a unique key field.
Now we perform this query:
INSERT INTO `t1` (`f1`, `f2`, `f3`) VALUES
('11', '12', '13'),
('21', '22', '23'),
('31', '32', '33'),
('41', '42', '43'),
('51', '52', '53')
ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id)
How do I get the last insert IDs of all the rows inserted/updated?
For the example above, I believe the IDs would be:
2
5
6
4
7
Right?
But how do I get them from MySQL after a batch INSERT query with ON DUPLICATE KEY UPDATE clause like this?
From this answer, LAST_INSERT_ID "gives you the id of the FIRST row inserted in the last batch" and one can simply get all the rest IDs in a sequential manner if the rows are all freshly INSERT-ed.
Apparently, when we have ON DUPLICATE KEY UPDATE, it's a totally different story. So is there any way to get all the last insert IDs of a batch INSERT with ON DUPLICATE KEY UPDATE? Tried google but found nothing helpful.
Why do I need this
After inserting in t1, I need to associate the rows just inserted with one of the rows in t2. It's a many-to-many relationship so I would need to insert in t1_x_t2 with the ID of the row from t2 and all the IDs just inserted in t1.
Is there any other way to achieve this?

You can use triggers in MySql for this purpose on events AFTER INSERT and AFTER UPDATE. In trigger body you will get the old and new values that you can use to insert, update or delete in another table. MySQL doc link: https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html

Related

Insert a row only if doesn't exist without getting its id

I followed this tutorial with 'INSERT IGNORE' first and 'INSERT ... ON DUPLICATE KEY UPDATE' then. But it doesn't work.
I'm using NodeJS to get some data from an API, and store these data into a mySQL database. Before storing data, I want to know if this row already exists.
The ID is AUTO_INCREMENT and I d'ont know this one. Instead of using async/await or promises in NodeJS, I wanted to treat this point with mySQL without knowing the ID.
I tried this one but it adds a new row with a new ID instead of another row already exists:
INSERT INTO test (nom, date, heure) VALUES ('123456', '2018-08-23', '10:45:00') ON DUPLICATE KEY UPDATE nom='123456', date='2018-08-23', heure='10:45:00';
After that, I tested this one, same result:
INSERT IGNORE INTO test (nom, date, heure) VALUES ('123456', '2018-08-23', '10:45:00')
Thanks for your help!
Set a unique index for the 3 columns:
ALTER TABLE test ADD UNIQUE un_index(nom, date, heure);
Then execute:
INSERT IGNORE INTO test (nom, date, heure) VALUES ('123456', '2018-08-23', '10:45:00');
If the 3 values already exist, the row will not be inserted.

MYSQL innerjoin insert Multiple tables

Hello i'll give you guys an example of the database tables that are being a pain so i got 3 conected tables yeah trying to make a list into a database anyway i'm having trouble writing a insert query for it
vogelsoort
id|naam|idhooftoonder|
now idhoofdtoonder references to the id a connection table to sort of translate a list to a mysql database (the logic of the table will be added underneath)
hoofdtoonder
|pkey|Id|idondersoorten
now idhoofdtoonder references to a the following table its id
ondersoort
id|naam
I'm sorry for asking this also i'm not experienced enough yet in mysql
edit: the question is since i've tried with a simple insert query it overwrote existing data that i'm looking for help with an insert without overwriting existing id's and connections since (idhootoonder references to hooftonder(id) and hooftoonder idontersoorten references to ondersoort(id) but not all data in ondersoort is connected to the same vogelsoort and i need an insert query that doesn't overide existing connections
You need 3 insert-statements, one for each table.
You may use TRANSACTION to do it safely.
You need to use LAST_INSERT_ID() function (your PK fields must been auto_increment for this), docs: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id
START TRANSACTION;
INSERT INTO ondersoort (id, naam) VALUES (NULL, 'data');
INSERT INTO hoofdtoonder (pkey, Id, idondersoorten) VALUES (NULL, NULL, LAST_INSERT_ID());
INSERT INTO vogelsoort (id, naam, idhooftoonder) VALUES (NULL, 'data', LAST_INSERT_ID());
COMMIT;

Insert to table or update if exists using MYSQL database

I have mysql database. I need to update country list on my table. there is some country in my table. I need to check that country if not exist and insert to the table. I'm used following sql script. But this is not working. when execute this code it will duplicate the record.
MySQL Query:
INSERT INTO `moneyexpressstore`.`countries` (`Name`, `Code`, `CurrencyId`) VALUES
('Australia', 'au', NULL) ON DUPLICATE KEY UPDATE Name=VALUES(Name)
thanks,
First make sure your database does not have duplicate records on column countries, then execute this
CREATE UNIQUE INDEX countriesindex ON countries (Name(50))
50 is the amount of characters that the index will search for "unique" values. For example if that number was 3, then these two different string would be considered the same, and a 1062 Duplicate Entry error would occur abcHELLO=abcWORLD and in your case it would force the UPDATE instead of INSERT.
If you get a 1062 error, that means you have duplicates in your db so find them remove them and try again.
After this your query will execute just fine and will update instead of duplicate on "Name"
Have a look in the documentation of mysql https://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Try this:
insert into `moneyexpressstore`.`countries` (id, `Name`, `Code`, `CurrencyId`) values(NULL,'Australia', 'au', NULL) on duplicate key update name=values(name)
Please refer this link:
http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html

mysql update multiple id/value pairs with one statement

If I have a mysql table with the 2 columns:
ID Date
1 2012-03-05
2 2012-02-21
3 2013-06-12
4 2011-01-15
5 2013-02-23
and I have an array of random updates such as
$arr = array('2'=>'2013-03-23','4'=>'2013-03-19','5'=>'2011-08-09');
(where the index is the ID and the value is the date)
is there a way to update the table with one statement?
the reason I am doing this, is because I need to make hundreds+ of changes and single updates would be alot of statements.
If ID is unique or a primary key, you can do
INSERT INTO `Table` (ID, `Date`)
VALUES ('2', '2013-03-23'), ('4', '2013-03-19'), ('5', '2011-08-09')
ON DUPLICATE KEY UPDATE `Date` = VALUES(`Date`)
Note that this might affect the auto increment value and it might insert new records into the table.

MySQL: mass insert new records or increment existing

I need to make something like this:
INSERT `stats` (`id`,`clicks`) VALUES
(1, clicks+7),
(2, clicks+3),
....
ON DUPLICATE KEY UPDATE `clicks`=VALUES(clicks)
in other words, when table has no record with pk id - it inserted and clicks gets 7 (or 3). When record with PK is present, then old value of click should be increased by 7 (or 3). As you can see, increment value for each row is different. Current query always overwrites old value. Please help to modify this query.
The VALUES have to be literal values, not references to columns:
INSERT INTO `stats` (`id`,`clicks`) VALUES
(1, 7),
(2, 3)
ON DUPLICATE KEY UPDATE `clicks`=`clicks` + VALUES(`clicks`)