This seems like a simple task, but I am struggling to find a way to do this. I have two tables (A and B) with the same structure. Both have an auto-increment primary key. I want the data from table B to go in to table A. I tried:
insert into A select * from B
However I get an error that a primary key already exists. I would like the new rows from table B to get a new primary key when I insert them in to table A - so basically discard the primary key from B but insert all the other columns. Seems like it should be a simple query but I can't figure it out. Thank you.
You're also selecting (and inserting) the auto_increment id, which fails if such id already exists. To let mysql automatically assign id just select and insert all values besides the id:
INSERT INTO A (foo, bar, baz)
SELECT foo, bar, baz FROM B
You must specify the columns you are want to insert from table B to table A, since you want to create a new id you can use a query as follow assuming column1 is they key that we don't want to insert.
insert into A (column2, column3) select column2, column3 from B
You can also lookup at this link that has some good query examples.
Related
I have an issue with duplicate entries in a database and due to the nature of the problem the easiest way to fix it would be to remove current duplicate rows and prevent further duplicates from being added .
Here is the table structure :
| a | b | c |
user url1 token1
photo url1 token2
action action1 token3
user url1 token4
photo url1 token5
action action2 token6
I want to prevent duplicate entries only when 2 columns are duplicated, in this case a and b .
So here we have user | url1 and photo | url1 duplicated twice.
I want to prevent any further duplicates from being added when both columns match another row at same time but the queries I found so far will consider each column separately and preventing any further duplicates to be added to any of them .
Can I achieve this with a mysql query using unique index ?
I tried using the following code :
Using ALTER TABLE `targets` ADD UNIQUE (
`a` ,
`b`
);
Your question:"Can I achieve this with a mysql query using unique index ?"
Answer is 100% yes.
There are two ways of creating index:
1. CREATE UNIQUE INDEX index_name
ON table_name (column1, column2, ...);
2. ALTER TABLE table_name
ADD UNIQUE index_name (column1, column2, ...);
However, this will only work if your table doesn't have existing duplicate data. Otherwise you'll receive an error message like this:
Query: CREATE UNIQUE INDEX index_name ON targets (a, b)
Error Code: 1062
Duplicate entry 'photo-url1' for key 'index_name'
Therefore, you need to:
create a new empty table similar to your targets table.
create unique index.
INSERT IGNORE data from the old table.
Rename targets to targets_old and targets_new to targets.
Example:
CREATE TABLE targets_new LIKE targets;
CREATE UNIQUE INDEX index_name
ON targets_new (a, b);
INSERT IGNORE INTO targets_new SELECT * FROM targets;
RENAME TABLE targets TO targets_old;
RENAME TABLE targets_new TO targets;
Thanks for the replies guys, but I found the solution in the meantime and it was much simpler !
It's called unique composite key and it allows to do exactly what I wanted :
ALTER TABLE targets ADD UNIQUE KEY `uidx` (a, b, c);
Problem fixed :)
i don't think you can specify a unique doublet property.
edit : mention by Salmon : An index specification of the form (key_part1, key_part2, ...) creates an index with multiple key parts
https://dev.mysql.com/doc/refman/8.0/en/create-index.html#create-index-unique
you could try :
SELECT * FROM database1.table1 WHERE a='user' AND b='url1';
if got return a number of rows then don't add to the database.
this way you can fully control what goes into the database instead of letting the table automatically ignore the fail condition.
I have a table like this:
uuid | username | first_seen | last_seen | score
Before, the table used the primary key of a "player_id" column that ascended. I removed this player_id as I no longer needed it. I want to make the 'uuid' the primary key, but there's a lot of duplicates. I want to remove all these duplicates from the table, but keep the first one (based off the row number, the first row stays).
How can I do this? I've searched up everywhere, but they all show how to do it if you have a row ID column...
I highly advocate having auto-incremented integer primary keys. So, I would encourage you to go back. These are useful for several reasons, such as:
They tell you the insert order of rows.
They are more efficient for primary keys.
Because primary keys are clustered in MySQL, they always go at the end.
But, you don't have to follow that advice. My recommendation would be to insert the data into a new table and reload into your desired table:
create temporary table tt as
select t.*
from tt
group by tt.uuid;
truncate table t;
alter table t add constraint pk_uuid primary key (uuid);
insert into t
select * from tt;
Note: I am using a (mis)feature of MySQL that allows you to group by one column while pulling columns not in the group by. I don't like this extension, but you do not specify how to choose the particular row you want. This will give values for the other columns from matching rows. There are other ways to get one row per uuid.
If I try to insert data into a table which already contains that primary key, it will clearly fail.
Is there a simple way to check whether the data I've failed to insert matches what is already in the table? (ie, if the non-primary key fields are the same as are already there for that primary key)
Ideally rather than get a single error, I would like to get 2 different errors when I attempt to insert a primary key that is already used:
- Error1: primary key constraint broken - data being inserted is already in table
- Error2: primary key constraint broken - attempt to enter different data for existing primary key
To check you can do something like this
SELECT COUNT(*) FROM
(
SELECT * FROM tab1
UNION
SELECT * FROM tab2
);
UNION removes duplicates so if rows in both tables are identical then above query will return identical result as
SELECT COUNT(*) FROM tab1;
OR
SELECT COUNT(*) FROM tab2;
Your question is not very detailed (e.g. how you insert this data?) so my answer in also quite generic, but I belive it will be useful for you.
Try it with this:
INSERT INTO yourTable (field1, field2, field3...)
SELECT yourValue1, yourValue2, yourValue3...
FROM dual
WHERE NOT EXISTS (SELECT *
FROM yourTable
WHERE field1 = yourValue1
AND field2 = yourValue2
AND field3 = yourValue3...);
This query checks your fields and only inserts when the record is not already there.
Here is the scenario:
I have 2 tables and 2 temporary tables. Before I insert user data to the official tables, I insert them to a temp table to let them do the checks. There is a company table with company info, and a contact table that has contact info. The contact table has a field called company_id which is a foreign key index for the company table.
Temp tables are set up the same way.
I want to do something like: INSERT INTO company () SELECT * FROM temp_company; and INSERT INTO contact () SELECT * FROM temp_contact
My question is, how do I transfer the foreign key from the temp_company to the newly inserted id on the company table using a statement like this? Is there a way to do it?
Currently I am:
grabbing the temp rows
going one by one and inserting them
grabbing the last insert id
then inserting the contacts afterwards with the new last insert id
I just don't know if that is the most efficient way. Thanks!
if you have the same number of columns in both tables and then you should just be able to use the syntax you have there? Just take out the (). Just make sure there aren't any duplicate primary keys:
INSERT INTO company SELECT * FROM temp_company;
INSERT INTO contact SELECT * FROM temp_contact;
You can also specifically specify the columns that get inserted, this way you can specify exactly which column you insert as the new ID.
INSERT INTO company (`ID`,`col_1`,...,`last_col`) SELECT `foreign_key_col`,`col_1`,...,`last_col` FROM temp_company;
INSERT INTO contact (`ID`,`col_1`,...,`last_col`) SELECT `foreign_key_col`,`col_1`,...,`last_col` FROM temp_contact;
Just make sure you are selecting the right # of columns.
I have a huge table of products but there are lot of duplicate entries. The table has more than10 Thousand entries and I want to remove the duplicate entries in it without manually finding and deleting it. Please let me know if you can provide me a solution for this
You could use SELECT DISTINCT INTO TempTable, drop the original table, and then rename the temp one.
You should also add primary and unique keys to avoid this sort of thing in the future.
for full row duplicates try this.
select distinct * into mytable_tmp from mytable
drop table mytable
alter table mytable_tmp rename mytable
Seems the below statements will help you in resolving your requirements.
if the table(foo) has primary key field
First step
store key values in temporary table, give your unique conditions in group by clause
if you want to delete the duplicate email id, give email id in group by clause and give the primary key name in
select clause like either min(primarykey) or max(primarykey)
CREATE TEMPORARY TABLE temptable AS SELECT min( primarykey ) FROM foo GROUP BY uniquefields;
Second step
call the below delete statement and give the table name and primarykey columns
DELETE FROM foo WHERE primarykey NOT IN (SELECT * FROM temptable );
execute both the query combined in your query analyser or db tool.
If the table(foo) doesn't have a primary key filed
step 1
CREATE TABLE temp_table AS SELECT * FROM foo GROUP BY field or fileds;
step 2
DELETE FROM foo;
step 3
INSERT INTO foo select * from temp_table;
There are different solutions to remove duplicate rows and it fully depends upon your scenario to make use of one from them. The simplest method is to alter the table making the Unique Index on Product Name field:
alter ignore table products add unique index `unique_index` (product_name);
You can remove the index after getting all the duplicate rows deleted:
alter table products drop index `unique_index`;
Please let me know if this resolves the issue. If not I can give you alternate solutions for that.
You can add more than one column to a group by. I.E.
SELECT * from tableName GROUP BY prod_name HAVING count(prod_name) > 1
That will show the unique products. You can write it dump it to new table and drop the existing one.