Duplicating a row in MySQL without recoding for database change - mysql

Given the following table structure:
ID
Field1
Field2
Field3
I would like to duplicate a record in the table. The pseudo code would look something like this:
DUPLICATE * IN MyTable WHERE ID = 3
Here are my constraints:
I don't want the ID duplicated.
I do not now how many fields or their types are in the table.
I do not want to do this in PHP.

You can use a select statement to insert rows. If you want to insert a new row with all of the same values, just write a select statement to get the values you want. Try something like this:
INSERT INTO myTable (field1, field2, field3)
SELECT field1, field2, field3 FROM myTable WHERE id = 3;
Here is an SQL Fiddle example.
EDIT
If you don't know how many fields, an option you have is to use a temporary table. See this article for example. The reason you need a temporary table, is because you cannot simply re-insert the row, because you will have a duplicate key error. So the logic will be as follows: Add row to new table, change the id, insert duplicated row with new id into old table, and drop the temporary table.
Assuming your id column is auto_increment, you can set the new id to the current maximum id + 1. You don't have to do that, but as long as you have some way of updating the id to something that does not already exist, this will work. Try this instead:
CREATE TEMPORARY TABLE temp SELECT * FROM myTable WHERE id = 3;
UPDATE temp SET id = (SELECT MAX(id) FROM myTable) + 1;
INSERT INTO myTable SELECT * FROM temp;
DROP TABLE temp;
Here is another SQL Fiddle example.

Related

SQL Insert from table to table prevented by duplicate primary key from source table

I am trying to populate a products table on MySQL with latest products, which are retrieved and stored in products_temp table.
So the method for this is straight forward, simply doing an INSERT to products from products_temp, as such:
INSERT INTO products ( select products_temp.* FROM products_temp )
Problem is, it results in a duplicate primary key error, because of the id from products_temp clashing with the id in products.
Can someone tell me how to fix this please?
I tried declaring the fields in the select statement without the id, but that results in "Column count doesn't match value count at row 1"
Any help would be appreciated.
Thanks!
You'll need to declare the columns except the ID on both the INSERT and the SELECT, since the number of fields need to match, and id (as you noticed) can't be inserted as is into the destination table.
INSERT INTO DestTable (field1, field2, field3)
SELECT field1, field2, field3 FROM SourceTable;
An SQLfiddle to test with.
EDIT: You could do it in a bit more hacky way to simplify the insert. You can create a trigger that simply forces the primary key to NULL on insert.
CREATE TRIGGER t_DT BEFORE INSERT ON DestTable
FOR EACH ROW
SET NEW.id = NULL;
then a copy from table to table can be done as simply;
INSERT INTO DestTable SELECT * FROM SourceTable;
Another SQLfiddle.
How about something like:
INSERT INTO products
(
select products_temp.* FROM products_temp
where key not in (select key from products)
)

Creating a table on the basis of a field

I have a MySql table which has about 100k rows. there is one field say id which contains numbers from 1-35. all these records fall in this range of id i.e. all these records have value of id column between 1-35.
Now i want to create another table which will have one row of each id. i.e the new table should have 35 rows only.
How to go about it ?
create table new_table (id int);
insert into new_table
select distinct id from big_table;
Edit:
You can create the new_table by outputting the big_table create script and changing the name.
SHOW CREATE TABLE big_table;
/* modify the name of the output and execute */
insert into new_table
select * from big_table group by id
You have a table with 100.000 rows, and you want a new table with 35 rows. What values do you want for the remaining columns?
If the answer is: doesn't matter, this works:
CREATE TABLE newTable
SELECT * FROM yourTable
GROUP BY ID;
If you only want the IDs,
CREATE TABLE newTable
SELECT DISTINCT ID FROM yourTable;
You can copy data from one table to another even difference database(Schema) as following
INSERT INTO [DestDatabase].[DestTablName]
SELECT [ColumnName] FROM [SourceDatabase].[SourceTablName];
So, you can use two way:
1:
INSERT INTO tbl_New
SELECT DISTINCT id from tbl_Original;
2:
INSERT INTO tbl_New
SELECT id from tbl_Original GROUP BY id;

Create Duplicate records with autonumber foreign keys

(using SS2008) Within a sql server database, I'd like to copy all the data of one client for a new client. In other words, generate exact duplicates of all records that pertain to client #1, except now the client ID field of the new records refer to client #2. This is all inside the same database.
Normally I would do this with a series of INSERT commands on the relevant tables selecting the client #1 records. However, some of the tables have autonumber ID columns, and these IDs are referenced as foreign keys in child tables. So when generating the child table records, I'd need to know and refer to the newly created autonumber Ids.
What is the cleanest way to go about this? Can it be done with SQL Server replication? My knowledge of SQL Server is pretty moderate.
I would do something like this:
-- Set up a placeholder for the new id
DECLARE #NewID INT;
-- INSERT parent record
INSERT INTO myTable (field1, field2)
SELECT field1, field2 FROM myTable WHERE ID = 1
-- Get the new ID
SET #NewID = (SELECT SCOPE_IDENTITY());
-- Insert child records with new id
INSERT INTO OtherTable (fkid, field1, field2)
SELECT #NewID, field1, field2 FROM OtherTable WHERE ID = 1
Now if we need to deal with thousands of records, this could work:
-- Add a new column in the database to manage where the record came from
ALTER TABLE myTable ADD ParentID int NULL
-- INSERT parent record
INSERT INTO myTable (field1, field2, ParentID)
SELECT
field1
, field2
, ID
FROM myTable
WHERE SomeCondition IS True
-- Insert child records with new id
INSERT INTO OtherTable (fkid, field1, field2)
SELECT
myTable.ID
, OtherTable.field1
, OtherTable.field2
FROM
OtherTable
INNER JOIN myTable ON OtherTable.FKID = myTable.ParentID
-- Once unneeded, drop the temporary column
-- ALTER TABLE myTable DROP COLUMN ParentID

Create a table from an old one selecting specific rows

how can I create a new table selecting specific rows of the old table ?
The selected 3 rows have field1 = 243, 245 and 248 respectively.
Also I need to select the rows with field1 > 0 from table3.
thanks
You can use CREATE TABLE...AS SELECT... to make a table defined by the columns and data types of a query result set:
CREATE TABLE NewTable AS
SELECT * FROM Table3
WHERE field1 IN (243,245,248);
I can't tell what you mean about field1>0. I'll leave that to you.
create table new_table like old_table;
insert into new_table select * from old_table where field1 in (243,245,248);
insert into new_table select * from table3 where field1 >0;

MySQL: Update all Columns With Values From A Separate Table

Sometimes if I want to quickly copy records from one table to another (that has the same structure) I use a query like this:
INSERT INTO table2 SELECT * FROM
table1 WHERE id = SOME_VALUE
How can I add a ON DUPLICATE KEY UPDATE to this statement? I tried this:
INSERT INTO SELECT * FROM table1 WHERE
id = 1 ON DUPLICATE KEY UPDATE SELECT
* FROM table1 WHERE id = 1
But I get an error. Is there away to accomplish the query above with out individually listing each column in the query?
P.S. Yes, I realize that it is not good practice to have multiple tables with identical structures, but sometimes you just don't get control over everything in the workplace!
The below UPDATES if there is no PK duplication and INSERTs is there is:
REPLACE INTO table2(field1, field2, field3)
SELECT field1, field2,field3 FROM table1
WHERE id=1;
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html Just use the SELECT field_name from the other table like in dnagirls example