Quickest way to duplicate a MySQL Record - mysql

Simple question, i have a query with some WHERE and i need to duplicate it with a change to 1 field to a different value? There is a unique increment ID field as well which I cannot duplicate.

Something along these lines should work. This will give you access to the row that you want to duplicate, and you just select the values to insert for the new row, replacing one of them.
INSERT tblData
( -- Lets pretend Column1 is your key
Column2
, Column3
)
SELECT
Column2
, Column3 + 5 /*Replace this with whatever value is you want*/
FROM tblData
WHERE Column1 = #Id

INSERT INTO table(field1,field2)
SELECT field1*x, field2 /*Replace accordingly*/
FROM table
WHERE key = #Id

Related

MySql. UPDATE if value exists - else INSERT (for not primary and not unique value)

I have my_table with column1 column.
If there are rows with column1='old' I want to update those rows.
Else, I want to insert a new row.
Something like this:
IF(
(EXISTS(
SELECT * FROM my_table WHERE column1='old'
)),
(UPDATE my_table SET column1='new' WHERE column1='old'),
(INSERT INTO my_table (column1) VALUES ('new') )
)
I use MySql so I cannot use IF on the beginning of query.
column1 is not unique and not primary. So I cannot use ON DUPLICATE KEY UPDATE or REPLACE

How to add 2 columns in mysql?

I have a table called "attendance" in which there are several columns.
I want to add 2 columns and put the result in the third column in the same table.
How to do it in Mysql?
I want it to happen every time when ever a new entry comes.
UPDATED: If you have no control over INSERT statements and you want your calculated column values to be persisted then you can use a BEFORE INSERT trigger
CREATE TRIGGER tg_bi_attendance
BEFORE INSERT ON attendance
FOR EACH ROW
SET NEW.column3 = NEW.column1 + NEW.column2;
Note: you probably have to cover a case when values in column1 and/or column2 are being updated. Use a separate BEFORE UPDATEtrigger for that.
CREATE TRIGGER tg_bu_attendance
BEFORE UPDATE ON attendance
FOR EACH ROW
SET NEW.column3 = NEW.column1 + NEW.column2;
Here is SQLFiddle demo
Otherwise just calculate it on the fly in SELECT clause
SELECT column1, column2, column1 + column2 column3
FROM attendance
or create a view
CREATE VIEW vw_attendance AS
SELECT column1, column2, column1 + column2 column3
FROM attendance
To update rows that are already in the table use UPDATE
UPDATE attendance
SET column3 = column1 + column2

MySQL CASE to update multiple columns

I would like to update multiple columns in my table using a case statement, but I cannot find how to do this (is this even possible). I came up with the following invalid reference query:
UPDATE tablename SET
CASE name
WHEN 'name1' THEN col1=5,col2=''
WHEN 'name2' THEN col1=3,col2='whatever'
ELSE col1=0,col2=''
END;
Is there any way of achieving the expected result with valid SQL?
UPDATE tablename
SET col1 = CASE WHEN name = 'name1' THEN 5
WHEN name = 'name2' THEN 3
ELSE 0
END
, col2 = CASE WHEN name = 'name1' THEN ''
WHEN name = 'name2' THEN 'whatever'
ELSE ''
END
;
I don't know of any clean way to do what you're asking. An equivalent valid SQL update would be:
UPDATE tablename SET
col1 = CASE name WHEN 'name1' THEN 5 WHEN 'name2' THEN 3 ELSE 0 END,
col2 = CASE name WHEN 'name1' THEN '' WHEN 'name2' THEN 'whatever' ELSE '' END;
Of course this isn't pretty and requires repeating the same cases (e.g. 'name1') multiple times, but I just don't think it's possible any other way.
If name has a unique index and your values are known to exist in the table, you can use this trick:
INSERT INTO tablename (name, col1, col2)
VALUES ('name1', 5, '')
, ('name2', 3, 'whatever')
ON DUPLICATE KEY UPDATE
col1 = VALUES(col1)
, col2 = VALUES(col2);
If there are any additional NOT NULL columns without a default value, you'll have to add dummy values for those. Just leave them out of the ON DUPLICATE KEY UPDATE and they'll be ignored.
You have two options that are covered in the different answers of this question:
UPDATE ... CASE
INSERT INTO ... ON DUPLICATE KEY
I had the following requirement:
bulk update 100000+ records with 4 column values
the source might have records that do not trigger the "ON DUPLICATE KEY" thus just inserting new data instead of just updating. At the same time I do not want these new records.
So there are two bad alternatives:
using UPDATE ... CASE for multiple columns makes this really expensive for the database when updating 100000+ records
using INSERT INTO ... ON DUPLICATE KEY might insert records that I do not want
My solution: Use INSERT INTO ... ON DUPLICATE KEY with dummy data, then delete all records that include column with the UNWANTED_INSERTED_DATA flag
I am inserting one column with UNWANTED_INSERTED_DATA as a flag where I can guarantee these values will never be part of any real data. The remaining columns are updated with the wanted data.
INSERT INTO tablename (name, col1, col2)
VALUES ('name1', 5, 'UNWANTED_INSERTED_DATA')
, ('name2', 3, 'UNWANTED_INSERTED_DATA')
ON DUPLICATE KEY UPDATE
name = VALUES(name)
, col1 = VALUES(col1)
; # DO NOT include the UNWANTED_INSERTED_DATA in the update part
The records I want only use update thus never receive the dummy data with UNWANTED_INSERTED_DATA column.
The records I do not want contain the dummy data.
I can then delete all unwanted inserted records with dummy data in one delete query:
DELETE FROM tablename WHERE col2 = 'UNWANTED_INSERTED_DATA'
This is a hacky solution but gets the job done with just two queries in two steps.

Select, Modify and insert into the same table

What's the easiest way to select a row, modify couple of columns and insert it to the same table?
I'm trying to insert a new row based on another.
INSERT INTO table2 (column1, column2, column3)
SELECT column1, 'no', column3 FROM table2 WHERE column2 = 'yes'
Hopefully this is a bit clearer as to how you do this. As you can see, I've grabbed two columns from table2 and for the other column I used a text value for instead of the value for column2.
Other patterns you can use:
Combine a column and some other text (Assumes the column is already a string data type.
INSERT INTO table2 (column1, column2)
SELECT column1 + 'no', column2 FROM table2 WHERE column2 = 'yes'
Combine a column and some text, One example where the column is a string and one where it is not.
INSERT INTO table2 (column1, column2)
SELECT column1 + 'no', 'A' + cast(column2 as Varchar (10)) FROM table2 WHERE column2 = 'yes'
INSERT INTO table(column1,column2) SELECT column1, const2 FROM table ...
The select list will likely mix copied columns (by name) and changed columns (by desired values).
Say column is int
INSERT INTO table(column1,column2) SELECT column1 + 1, column2 -1 FROM table
You can multiply columns and perform string functions.

#1062 - Duplicate entry '1' for key 1 - No duplicate entries found

So when trying to add an autoincrement to a field it comes up with #1062 - Duplicate entry '1' for key 1 . I've tried removing the primary key and re-adding it and that works fine (which I assume wouldn't if there was duplicates?)
But when I try to add an autoincrement to the field it throws an error. It gives me a browse option which runs the following SQL:
SELECT *
FROM `myTbl`
WHERE CONCAT_WS( "-", 11 ) = "1"
ORDER BY 11
LIMIT 0 , 30
However this returns a empty result set.. suggesting there are no duplicates. So if there are no duplicates, how come i can't add an autoincrement?
Do you have any rows with value 0 or NULL for this column? ALTER TABLE can cause primary keys to be resequenced. In the case of a key of 0, MySQL will try to give it the value 1, which will fail if the key 1 already exists.
Try changing any 0 or NULL values in the column to something higher (and unused).
Michael Mior's answer works if you can change the data in the table. However, there is also a workaround that lets you keep the data intact (I've tested this on MySQL 5.5). Remember that having a zero value as a primary key in MySQL is not a recommended practice just for this reason. If you can get rid of the zero, then do it.
Disable automatic value generation when a zero is inserted:
SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
Add AUTO_INCREMENT to your column:
ALTER TABLE ... AUTO_INCREMENT;
Re-enable automatic value generation:
SET SQL_MODE='';
It should be obvious that inserting data to the table during this whole operation can not be allowed. Otherwise there will be unwanted zero values in the column.
SELECT * <<-- Select * is an anti-pattern
FROM myTbl
WHERE CONCAT_WS( "-", 11 ) = "1" <<-- You are not selecting a column
ORDER BY 11 <<-- This however does refer to a column.
LIMIT 30 OFFSET 0
rewrite the query to
SELECT field1, field2, field3, ...., field11
FROM myTbl
WHERE COALESCE(field1, field2, field3, field11) = '1'
ORDER BY field11
LIMIT 30 OFFSET 0
If you want to insert a row use code like this:
INSERT INTO table1 (/*do not list the PK!*/ field2, field3, field4)
VALUES ('a', 'test' ,'b' ,'example');
If you want to select all duplicate rows use:
SELECT id, count(*) as duplicate_count
FROM table1
GROUP BY id
HAVING duplicate_count > 1
You will need to update those id's that are listed as duplicate.
Another option is to add an extra column and drop the old PK.
ALTER TABLE table1 ADD COLUMN new_id unsigned integer not null auto_increment primary key;
ALTER TABLE table1 DROP COLUMN id;
ALTER TABLE table1 CHANGE COLUMN newid id;