Is there a way to accomplish a single table scan in MySQL with an UPDATE? The following is a standard example:
IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue')
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
ELSE
INSERT INTO Table1 VALUES (...)
This is the ideal situation I'd like to happen in MySQL (But this is MsSQL):
UPDATE user SET (name = 'jesse') WHERE userid ='10001'
IF ##ROWCOUNT=0
INSERT INTO user (name) VALUES('jeeeeee')
It's sort of reversed in MySQL. You perform the insert, and if the key already exists, then update the row:
INSERT INTO Table1 (col1,col2,col3) VALUES (val1,val2,val3)
ON DUPLICATE KEY UPDATE col1 = val1, col2 = val2, col3 = val3;
This is predicated on you having a unique key for the table (which you do, right?)
Related
I want to insert or update a record in a table. If it doesn't exist, it should be inserted. If it exists, then I only want to update the record if a certain condition is met. Is there a way to do this using a single INSERT statement? Something like this:
CREATE TABLE test1 SELECT 1 id, now() dt;
ALTER TABLE test1 ADD PRIMARY KEY (id);
INSERT IGNORE INTO test1 (id, dt) VALUES
(1, '2023-02-06 13:00:00')
ON DUPLICATE KEY UPDATE dt = VALUES(dt) WHERE dt = somedatetime;
-- i.e. always insert, but only update dt if existing dt value is something specific
I know I can do this using a transaction, I'm just wondering if something like this can be done in a single statement.
I was trying things out while writing the question and I found this to be one solution:
INSERT IGNORE INTO test1 (id, dt)
SELECT 1, '2023-02-06 13:00:00'
FROM test1
WHERE (NOT EXISTS(SELECT * FROM test1 WHERE id = 1))
OR (id = 1 AND dt = somedatetime)
ON DUPLICATE KEY UPDATE dt = VALUES(dt);
In MySQL I have a table with almost 100 columns and 33 000 rows of data stored in it. And i'm trying to run a procedure that will update all the columns in a table or insert new row in a table according to some condition. Something like that:
IF (v_Rows > 0) then
UPDATE tab1 SET
col1 = var1,
col2 = var2,
. . .
col95 = var95
WHERE id = var_id
ELSE
insert into tab1 values
(var1, var2, ... var95)
END IF;
These statements takes too much time to execute. And I'm curious about how such structure can be optimized?
See INSERT ... ON DUPLICATE KEY UPDATE ...
It uses a unique key to decide whether the row already exists, then...
If it does not exist, it INSERTs;
If it does exist, it updates whatever you specify.
Use col22 = VALUES(col22) to avoid having the 'update' to the var22, which is already provided. See VALUES().
If you have multiple rows to apply at the same time in the same way,
INSERT INTO tbl (col1, ...)
SELECT col1, ... FROM source_tbl ...
ON DUPLICATE KEY col1 = VALUES(col1), ...;
I know about ON DUPLICATE USE KEY clauses. But I can not use it since I want to update and insert on non-unique column.
I have table1 and table2. I want to create a trigger on table1.
Pseudocode:
IF id_code for corresponding id_name from table1 is present in table2
then update record in table 2
else record in table2.
For Ex.
table1 has column1 id_code, column2 id_name
table2 has column1 id_code, column2 status
IF id_code for corresponding id_name from table1 is present in table2
UPDATE status column in table2.
ELSE insert id-code in table2
Best way would probably be to use a conditional statement, since as you said you are checking for a non unique value and thus cannot use ON DUPLICATE KEY:
IF EXISTS (SELECT id_code FROM table2 WHERE id_code = 'code from table1') THEN
UPDATE table2 SET status = 'new status' WHERE id_code = 'code from table1';
ELSE
INSERT INTO table2 (id_code, status) VALUES ('code from table1', 'new status');
END IF;
The only caveat here is that control structures are only valid in stored procedures, so you will need to put this in a stored procedure or a trigger.
I tried to insert a complete row to a table. But the problem is, that I use the same IDs. Is there a easy way to insert a complete row expect the one value (ID)?
INSERT INTO new_table SELECT * FROM old_table WHERE q_value = 12345
I would not insert every single value, because there are hunderds of columns.
Thanks for your help in advance,
Yab86
May be Something like this
You can do without getting column2
Insert Into new_table (Column1,Column3,Column4 ...)
Select Column1,Column3,Column4 ... From old_table
WHERE q_value = 12345
If ID is part of a unique key the only (good) way is to write out all the other columns, like this
insert into new_table
values (col1, col2, col3)
select col1, col2, col3
from old_table
where q_value = 12345;
If ID isn't part of the unique key there might be some ways to do it in two queries (easier to write but perhaps not better)
insert into new_table
select *
from old_table
where q_value = 12345;
update new_table
set ID = null
where q_value = 12345;
If the first column in new_table is your auto_increment primary id, you could use this, but then you cannot use the asterisk and have to list all columns except the first one (0 will do the trick for your auto_increment, that means it will insert the incremented value of the autoindex):
INSERT INTO new_table
SELECT 0, column2, column3, ...
FROM old_table WHERE q_value = 12345
I usually copy data into tabelB from table A daily by the following query:
REPLACE INTO tableB (id,col1,col2,col3) SELECT id,col1,col2,col3 FROM tableA WHERE date='somedate'
Here REPLACE is used as if the script is being run double for a particular date by mistake, it will not copy the tableA two times into tableB. But problem is, tableB has two unique key index (id and col1). So if REPLACE is executed more than once, index is deleted and recreated by this REPLACE command. To avoid this thing, I want to use:
INSERT INTO tableB (id,col1,col2,col3) VALUES (val1,val2,val3,val4) ON DUPLICATE KEY UPDATE col2=VALUES(col2),col3=VALUES(col3)
But as I am copying the tableA here, I cant use the above INSERT........ON DUPLICATE KEY UPDATE query, I have to use SELECT command to copy data from tableA.
So how to modify INSERT INTO ........... ON DUPLICATE KEY UPDATE query, so that it can copy the tableA and at the same time if execute the script more than once, it just updates the data.
Regards
Try this INSERT query -
INSERT INTO tableB (id, col1, col2, col3)
SELECT id, col1, col2, col3 FROM tableA WHERE date = 'somedate'
ON DUPLICATE KEY UPDATE col2 = VALUES(col2), col3 = VALUES(col3);