MySQL: mass insert new records or increment existing - mysql

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

Related

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

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

MYSQL ON DUPLICATE KEY UPDATE and IGNORE in one query

Ik execute a query that inserts some values in de table, if a combination of ID, Year, rownum (unique index) exists that i do a regular ON DUPLICATE KEY UPDATE and so the row is updated. The query looks like this:
INSERT INTO data_advertenties_prijzen (`ID`, `year`, `rownum`, `status_prijs`,
`datum_dag`, `timestamp_dag`)
VALUES (100,2014,1,1,'2014-01-01',1388534400),
(100,2014,2,1,'2014-07-16',1405468800),
(100,2014,3,1,'2014-07-26',1406332800)
ON DUPLICATE KEY UPDATE
status_prijs = VALUES(status_prijs),
datum_dag = VALUES(datum_dag),
timestamp_dag = VALUES(timestamp_dag)
Nothing difficults there, but….
I also want to do a ON DUPLICATE IGNORE for 1 value in the same query. I Also want to insert one row for 2015. For example: (100,2015,1,1,'2015-01-01',1405468800)…
If there is already a row with ID=100, Year=2015 And rownum=1 the insert of that row must be ignored.
How to do that?
You could change the values conditionally in the ON DUPLICATE clause.
I did this experiment to make sure it works:
INSERT INTO data_advertenties_prijzen VALUES (100, 2014, 1, 7, now(), 1406332800)
ON DUPLICATE KEY UPDATE
status_prijs = IF((id,year,rownum)=(100,2015,1), status_prijs, VALUES(status_prijs)),
datum_dag = IF((id,year,rownum)=(100,2015,1), datum_dag, VALUES(datum_dag)),
timestamp_dag = IF((id,year,rownum)=(100,2015,1), timestamp_dag, VALUES(timestamp_dag));
So if I try to insert a specific trio of id/year/rownum, it just uses the existing value, else if it's some other id/year/rownum, it uses the VALUES I specify in the INSERT.
Unfortunately, you must repeat the expression for each column you want to update.

MySQL Query sets values to 0 with 'AND' clause

I have a MySQL query that is meant to update two columns by increments of 1, or create them if they do not exist.
My current table has four columns: id, username, playtime, and deathtime.
As it stands now, this is the query I use:
INSERT INTO `playTime` (`username`, `playtime`, `deathtime`)
VALUES ('Rogue', 1, 1)
ON DUPLICATE KEY UPDATE `playtime`=`playtime`+1
AND `deathtime`=`deathtime`+1
(The username is dynamic in application, but one is provided for the example).
My issue, however, is that on a duplicate key it doesn't increment the values, rather it sets both values to 0. Through numerous tests of tweaking the query, I have found that it is the AND clause that causes the query to "reset" the values. For instance, this query will increment the playtime column correctly:
INSERT INTO `playTime` (`username`, `playtime`, `deathtime`)
VALUES ('Rogue', 1, 1)
ON DUPLICATE KEY UPDATE `playtime`=`playtime`+1
And if you swap "playtime" with "deathtime", then it increments the other column correctly. Why is this?
Use a comma to delimit statements here.
INSERT INTO `playTime` (`username`, `playtime`, `deathtime`)
VALUES ('Rogue', 1, 1)
ON DUPLICATE KEY UPDATE `playtime`=`playtime`+1, `deathtime`=`deathtime`+1
The example can be seen in the documentation here: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Try this.. a comma, instead of AND
INSERT INTO `playTime` (`username`, `playtime`, `deathtime`)
VALUES ('Rogue', 1, 1)
ON DUPLICATE KEY UPDATE `playtime`=`playtime`+1 ,
`deathtime`=`deathtime`+1

SQL `update` if combination of keys exists in row - else create new row

First of, I've searched this topic here and elsewhere online, and found numorous articles and answers, but none of which did this...
I have a table with ratings, and you should be able to update your rating, but not create a new row.
My table contains: productId, rating, userId
If a row with productId and userId exists, then update rating. Else create new row.
How do I do this?
First add a UNIQUE constraint:
ALTER TABLE tableX
ADD CONSTRAINT productId_userId_UQ
UNIQUE (productId, userId) ;
Then you can use the INSERT ... ON DUPLICATE KEY UPDATE construction:
INSERT INTO tableX
(productId, userId, rating)
VALUES
(101, 42, 5),
(102, 42, 6),
(103, 42, 0)
ON DUPLICATE KEY UPDATE
rating = VALUES(rating) ;
See the SQL-Fiddle
You are missing something or need to provide more information. Your program has to perform a SQL query (a SELECT statement) to find out if the table contains a row with a given productId and userId, then perform a UPDATE statement to update the rating, otherwise perform a INSERT to insert the new row. These are separate steps unless you group them into a stored procedure.
Use a REPLACE INTO query.
REPLACE INTO table (productId, userId, rating) VALUES ('product id', 'user id', 'rating');
REPLACE INTO is like a normal insert, except if it finds a row already in the table with the same unique key it will delete that row before inserting.

MySql: REPLACE INTO with number=number+1

I would like do something like this in one only query.
REPLACE INTO table ( id, number ) VALUES ( 'test', number=number+5 )
What I want is (the first time!) insert the row and set the number 5.
the other times (if already exist) add 5 at the number.
Is it possible? I can't find nothing on line.
just be sure that ID is unique. Use INSERT ... ON DUPLICATE KEY UPDATE Syntax
INSERT INTO tableName (id, number)
VALUES ('test', 5)
ON DUPLICATE KEY UPDATE
number = number + 5
Assuming that id is a proper key (e.g. primary key):
INSERT INTO `table` (id, number)
VALUES ('test', 5)
ON DUPLICATE KEY UPDATE number=number+VALUES(number)