Insert multiple rows in single query and update existing - mysql

Is it possible to insert multiple rows in single query but in the same time check if record exist and update existing record?
I have to avoid REPLACE INTO because my table have primary and unique keys.

I'm not sure where to put ON DUPLICATE KEY in my query?
insert into mytable (A, B C) values
('a','b',1),
('c','d',2),
('e','f',3) ON DUPLICATE KEY UPDATE A = VALUES(A), B = VALUES(B), C = VALUES(C)
This is solution:
insert into mytable (A, B C) values
('a','b',1),
('c','d',2),
('e','f',3) ON DUPLICATE KEY UPDATE A = VALUES(A), B = VALUES(B), C = VALUES(C)
Thanks to all!

Related

Efficiency of Insert into on duplicate key update with many if expresssion

I'm trying to optimize the efficiency of one sql
it looks like:
Insert into order_table ( id, business_line, order_type,...)
values(1123123,4,5,·····)
ON DUPLICATE KEY UPDATE
business_line = IF( _version <= 6 ,10,business_line),
order_type = IF( _version <= 6 ,2,order_type)
..........
With many if condition
And it runs slow.(about 250ms)
Is there any way to bind so many 'if' together? Such as:
Insert into order_table ( id, business_line, order_type,...)
values(1123123,4,5,·····)
ON DUPLICATE KEY UPDATE
SET (business_line,order_type,...) =
IF( _version <= 6 ,(10,2),(business_line,order_type)),
..........
Any suggest will be appreciated
When the goal is to "UPDATE" several specific rows. Use a unique key (such as id):
INSERT INTO t
(id, a,b,c)
VALUES
(654, 1,2,3),
(666, 11,22,33),
...
ON DUPLICATE KEY UPDATE
b = VALUES(b),
c = VALUES(c);
When the goal is to "INSERT" several new rows. Don't supply any unique value (such as an AUTO_INCREMENT id):
INSERT INTO t
(id, a,b,c)
VALUES
(NULL, 1,2,3),
(NULL, 11,22,33),
...
ON DUPLICATE KEY UPDATE
b = VALUES(b);
Equivalently, leave out the AUTO_INCREMENT column and the NULLs.
Note: Version 8.0 wants this syntax instead:
b = NEW.b
(Caveat: Test this in your environment; I have not experimented with all variations.)
This technique should be faster because:
Only one roundtrip to the server
If autocommit=ON, then only one transaction for the batch.

Update and add new records table with join in MySQL

I have main table, mytable, with columns id,a,b,c,d
and a Temp_TABLE with columns id,b,c
I want to update mytable with the values on
temp Temp_TABLE, and if the records are not in mytable then insert them.
So far I have the following:
UPDATE mytable
JOIN
Temp_TABLE
ON mytable.profileId = Temp_TABLE.profileId
SET mytable.b = Temp_TABLE.b
mytable.c = Temp_TABLE.c
But this only works for the first part.
How can I insert the the records from Temp_TABLE into mytable
In MySQL, use insert on duplicate key update. But first you have to define the criteria for recognizing duplicates. For that, you need a unique index (or constraint):
create unique index unq_mytable_profileId on mytable(profileid);
Then:
insert into mytable (profileid, b, c)
select tt.profileid, tt.b, tt.c
from temp_table tt
on duplicate key update b = values(b), c = values(c);

Update if tuple is in the set, else insert in MySQL

I ran some query and got a set of tuples like ((A1,B1), (A2,B2), (A3,B3)....).
I need to check if a tuple from above set exists in a table XYZ(A,B,C). If it exists, then update C else insert (Ax,Bx,C) into the table.
I tried using the below query but it doesn't work. Is there any other way?
CASE WHEN EXISTS (SELECT * from XYZ as t where (t.A, t.B) in (select u.A, u.B from diff_table as u)) THEN
THEN UPDATE XYZ as v SET C = 1 WHERE (v.A, v.B) = (t.A, t.B) ELSE
INSERT INTO XYZ (A,B,C) values (u.A, u.B, 1) END;
I'd do it the other way round:
Update the ones that exist
Insert the ones that don't
Or if you have primary keys
Insert all with default value for C (existing will get rejected)
Update all
The functionality you want is insert . . . on duplicate key insert.
First, you need an appropriate index (if you don't have one):
create index idx_xyz_a_b on xyz(a, b)
Then:
insert into xyz(a, b, c)
select dt.a, dt.b, 1
from diff_table dt
on duplicate key update set c = 1;
By the way, if the value already exists, are you sure you want to set it to 1 instead of incrementing it?
insert into xyz(a, b, c)
select dt.a, dt.b, 1
from diff_table dt
on duplicate key update set c = c + 1;

INSERT or UPDATE from another table in mysql

I have two tables, with same schema -
create table test1 (
a INT NOT NULL ,
b INT NOT NULL ,
c INT,
PRIMARY KEY (a,b)
);
create table test2 (
a INT NOT NULL ,
b INT NOT NULL ,
c INT,
PRIMARY KEY (a,b)
);
I want to insert values from test2 table into test1, but if the row with same primary key already exist, update it. I know in mysql you can do similar thing with ON DUPLICATE KEY UPDATE like -
INSERT INTO test1 VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=3;
But I dont know how to do the above query with a SELECT from another table. What I am looking for is a query of form -
INSERT INTO test2
SELECT a, b, c FROM test1
ON DUPLICATE KEY UPDATE c = c + t.c
(Select a, b, c from tests1)t;
This query is obviously invalid. I would appreciate if somebody can make a valid query out of it.
This should work for you:
INSERT INTO test2
SELECT a, b, c as c1 FROM test1
ON DUPLICATE KEY UPDATE c = c + c1
You could do it with this SQL:
INSERT INTO test1 (a, b, c)
SELECT t.a as a, t.b as b, t.c AS c FROM test2 AS t
ON DUPLICATE KEY UPDATE c=t.c;
It depends, I use the PK autoincrement feature, for Row Unique identifier, I split a big table, so the small one have changes I can't miss, I read several opinions, even merge and remake PK that's do not work for me. The result set in Memory looks like if you don't mention the full columns name you will have errors. I did this and work, I hope some body have a better and smaller solutions:
>INSERT
>INTO t_traffic_all
>SELECT
>t_traffic.file_id,
>t_traffic.cust,
>t_traffic.supp,
>.
>. (a lot...)
>.
>t_traffic.i_traffic_type,
>t_traffic.date_posted,
>t_traffic.date_update
>FROM t_traffic
>ON DUPLICATE KEY UPDATE
>t_traffic_all.file_id = t_traffic.file_id,
>t_traffic_all.cust = t_traffic.cust,
>t_traffic_all.supp = t_traffic.supp,
>t_traffic_all.imprt = t_traffic.imprt,
>.
>.
>.
>t_traffic_all.i_traffic_type= t_traffic.i_traffic_type,
>t_traffic_all.date_posted= t_traffic.date_posted,
>t_traffic_all.date_update= t_traffic.date_update
> Affected rows: 11128
> Time: 29.085s
the total rows processed where 18608, so it insert 11128 and update 7480 (7554 should be) this numbers do not are very precise but the result was.

finding value of column after ON DUPLICATE KEY UPDATE

Consider this statement:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE d=d+1;
I need the value of d.
Is it possible to obtain it without performing a further SELECT?
There is a unique index on a,b,c. Would this index be used for better performance? This table will have a large number of rows.
Assuming you will be running both queries using the same connection, You can use the LAST_INSERT_ID(expr) function to set the current value of d, and check the value of LAST_INSERT_ID() together with the ROW_COUNT() function to find out if the record was inserted or updated:
INSERT INTO table (a,b,c)
VALUES (1,2,3)
ON DUPLICATE KEY UPDATE d = LAST_INSERT_ID(d + 1);
SELECT IF(ROW_COUNT() = 2, LAST_INSERT_ID(), 0 /*default value*/) ;
You can also use session variables:
INSERT INTO table (a,b,c)
VALUES (1,2,3)
ON DUPLICATE KEY UPDATE d = #tmp := (d + 1);
SELECT IF(ROW_COUNT() = 2, #tmp, 0 /*default value*/) ;