I am importing some data from a csv file into MySQL and trying to ignore duplicate rows.
mysql_query("INSERT IGNORE INTO products (parent_product_url, child_product_url, swatch) VALUES ('".$row[0]."', '".$row[1]."', '".$row[2]."')");
My csv file.
polo.htm,red.htm,red.jpg
polo.htm,green.htm,green.jpg
round-neck.htm,green.htm,green.jpg
Now if I run below csv file it should ignore first three rows as they already exists in the table. It should insert only fourth row.
polo.htm,red.htm,red.jpg
polo.htm,green.htm,green.jpg
round-neck.htm,green.htm,green.jpg
v-neck.htm,red.htm,red.jpg
I prefer on duplicate key update because insert ignore ignores all errors, not just duplication errors.
Regardless of which you use, your problem is probably the lack of unique constraint/index.
You don't specify what you mean by "duplicate". Assuming you mean all the columns:
create unique index unq_products_3 on products(parent_product_url, child_product_url, swatch);
Note: there is a maximum length to the keys used for indexes, depending on the storage engine. If your columns are too long, you may need to think about other approaches.
Records are inserted again when you re-execute insert statements because the inserts are not violating any unique or primary key index. Therefore MySQL doesn't have anything to ignore.
create table products (
parent_product_url varchar(100),
child_product_url varchar(100),
swatch varchar(100)
);
-- this will enter both records
insert ignore into products values ('polo.htm', 'red.htm', 'red.jpg');
insert ignore into products values ('polo.htm', 'green.htm', 'green.jpg');
-- this will enter both records **AGAIN**
insert ignore into products values ('polo.htm', 'red.htm', 'red.jpg');
insert ignore into products values ('polo.htm', 'green.htm', 'green.jpg');
Now let's add uniqueness to parent_product_url and try again:
truncate table products;
create unique index uk_products_parent_product_url on products(parent_product_url);
insert ignore into products values ('polo.htm', 'red.htm', 'red.jpg');
insert ignore into products values ('polo.htm', 'green.htm', 'green.jpg');
This will enter only the first record. 2nd record will be ignored and a warning will be thrown. No error will be thrown.
If you desire to have a combination of the 3 columns to be unique, then you would do this (This is what Gordon Linoff has mentioned also...I am just adding more context):
alter table products drop key uk_products_parent_product_url;
create unique index uk_products_parenturl_childurl_swatch on
products(parent_product_url, child_product_url, swatch);
insert ignore into products values ('polo.htm', 'red.htm', 'red.jpg');
insert ignore into products values ('polo.htm', 'green.htm', 'green.jpg');
Now you will see only two records inserted even when you re-execute the same 2 insert statements many times.
From https://dev.mysql.com/doc/refman/5.5/en/insert.html
If you use the IGNORE keyword, errors that occur while executing the
INSERT statement are ignored. For example, without IGNORE, a row that
duplicates an existing UNIQUE index or PRIMARY KEY value in the table
causes a duplicate-key error and the statement is aborted. With
IGNORE, the row is discarded and no error occurs. Ignored errors may
generate warnings instead, although duplicate-key errors do not.
I got it solved with the help of this Answer -> Insert query check if record exists - If not, Insert it
Below is my updated query
mysql_query("INSERT INTO products (parent_product_url, child_product_url, swatch)
SELECT * FROM (SELECT '".$row[0]."', '".$row[1]."', '".$row[2]."') AS tmp
WHERE NOT EXISTS (
SELECT * FROM products WHERE parent_product_url='".$row[0]."' AND child_product_url='".$row[1]."' AND swatch='".$row[2]."'
);");
Related
I have searched for an answer for days, however I can't seem to find the right solution. Therefore, I ask the following question:
Suppose I have a table with a column ID which is an AUTO_INCREMENT field and a column Word which is unique. I run the following queries:
"INSERT IGNORE INTO Table (Word) VALUES('Test')"
"INSERT IGNORE INTO Table (Word) VALUES('Test1')"
"INSERT IGNORE INTO Table (Word) VALUES('Test2')"
"INSERT IGNORE INTO Table (Word) VALUES('Test')" //THIS ONE WILL BE IGNORED
The problem is I can't get the last $mysqli->insert_id from the last query, because it isn't inserting anything. However I need this ID which is already in the DB. therefore, I thought I should use a ON DUPLICATE KEY UPDATE statement, however this leads to the situation where AUTO_INCREMENT is skipping values, because it updates the value but ALSO increments the AUTO_INCREMENT value although this value isn't assigned to any row.
So in the end, I end up with a table like this:
ID |Word
1 |Test
2 |Test1
3 |Test2
//Trying to insert words that where already in the table..
12 |Test3
//Trying to insert words that where already in the table..
17 |Test4
My answer would be to first retrieve the id for the word from the table and only if it fails to insert it. In both cases you have the id ready.
My guess is also that it will be faster this way around since you are not creating any ignored errors in mysql.
Is there a way to INSERT IGNORE INTO, with a composite key of certain columns?
INSERT IGNORE INTO `table1` WHERE `col_a` = 1 AND `col_b` = 2;
Where there is a composite key of col_a_col_b.
So basically it would ignore duplicates of certain row combinations?
Right now i've made a PHP function to ween out duplicates before inserting, but it's incredibly slow. I was wondering if SQL could do it alone?
Is this what you are looking for?
INSERT IGNORE INTO table1(col_a, col_b)
select 1, 2;
This will insert the value pair (1, 2) every time you run it. If you only want the pair to exist once, then you need a unique constraint. The easiest way is with an index:
create unique index table1(col_a, col_b);
Then the above will work the first time, but fail for subsequent inserts. By the way, for this functionality, I prefer:
INSERT INTO table1(col_a, col_b)
select 1, 2
on duplicate key update col_a = values(col_a);
insert ignore ignores all errors. This will only ignore errors caused by duplication -- nothing will happen and no errors will be returned.
i have a contactnumber column in mysql database. In contactnumber column there are more than 20,000 entries. Now when i upload new numbers through .csv file, i dont want duplicate numbers in database.
How can i avoid duplicate numbers while inserting in database.
I initially implemented logic that checks each number in .csv file with each of the number in database.
this works but takes lot of time to upload .csv file containing 1000 numbers.
Pleae suggest how to minimize time required to upload .csv file while not uploading duplicate values.
Simply add a UNIQUE constraint to the contactnumber column:
ALTER TABLE `mytable` ADD UNIQUE (`contactnumber`);
From there you can use the IGNORE option to ignore the error you'd usually be shown when inserting a duplicate:
INSERT IGNORE INTO `mytable` VALUES ('0123456789');
Alternatively, you could use the ON DUPLICATE KEY UPDATE to do something with the dupe, as detailed in this question: MySQL - ignore insert error: duplicate entry
If your contactnumber should not be repeated then make it PRIMARY or at least a UNIQUE key. That way when a value is being inserted as a duplicate, insert will fail automatically and you won't have to check beforehand.
The way I would do it is to create a temporary table.
create table my_dateasyyyymmddhhiiss as select * from mytable where 1=0;
Do your inserts into that table.
and then query out the orphans on the between mytable and the temp table based on contactnumber
then run an inner join query between the two tables and fetch out the duplicate for your telecaller tracking.
finally drop the temporary table.
Thing that this does not address are duplicates within the supplied file (don't know if that would be an issue in this problem)
Hope this help
If you don't want to insert duplicate values in table and rather wants to keep that value in different table.
You can create trigger on table.
like this:
DELIMITER $$
CREATE TRIGGER unique_key BEFORE INSERT ON table1
FOR EACH ROW BEGIN
DECLARE c INT;
SELECT COUNT(*) INTO c FROM table1 WHERE itemid = NEW.itemid;
IF (c > 0) THEN
insert into table2 (column_name) values (NEW.itemid);
END IF;
END$$
DELIMITER ;
I would recommend this way
Alter the contactnumber column as UNIQUE KEY
Using phpmyadmin import the .csv file and check the option 'Do not abort on INSERT error' under Format-Specific Options before submitting
I am running a insert statement to insert data, but I want to check for any duplicate entries based on date and then do an entry.
All I want is if today a user enters product_name='x', 'x' is unique so that no one can enter product name x again today. But of course the next day they can.
I do not want to run a select before the insert to do the checking. Is there an alternative?
You can either use
1. Insert into... on duplicate update
2. insert.. ignore
This post will answer your question
"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
You can use the mysql insert into... on duplicate update syntax which will basically enter in a new row if one isn't there, or if the new row would have caused a key constraint to kick in, then it can be used to update instead.
Lets say you have the following table:
MyTable
ID | Name
1 | Fluffeh
2 | Bobby
3 | Tables
And ID is set as the primary key in the database (meaning it CANNOT have two rows with the same value in it) you would normally try to insert like this:
insert into myTable
values (1, 'Fluffster');
But this would generate an error as there is already a row with ID of 1 in it.
By using the insert on duplicate update the query now looks like this:
insert into myTable
values (1, 'Fluffster')
on duplicate key update Name='Fluffster';
Now, rather than returning an error, it updates the row with the new name instead.
Edit: You can add a unique index across two columns with the following syntax:
ALTER TABLE myTable
ADD UNIQUE INDEX (ID, `name`);
This will now let you use the syntax above to insert rows while having the same ID as other rows, but only if the name is different - or in your case, add the constraint on the varchar and date fields.
Lastly, please do add this sort of information into your question to start with, would have saved everyone a bit of time :)
I need to create a insert and update statement, when today date is not in the database it will insert else it will update the QTY (from excel [this part I have done]) get from today.
But, there have a lots of row need to be insert and update.
1) it will check for the last 4 days in database, if there doesn't include today, it will just insert the data for today and update the last 3 days data. in the other hand, if there contain today it will just update.
P.S: I had try to use INSERT... ON DUPLICATE KEY UPDATE but it only 1 row affected.
If else statement , when i used this it only insert one row of data then the rest it just doing update.
Can give me some advise or example.
suppose you bulk copy your data from excel to a temporary table tbl and your actual table is tbl1 then do something like this
begin transaction;
if not exists(select * from tbl(updlock holdlock) where...)
begin
insert into tbl1...
else
begin
update tbl1...
end
commit;
What language are you using to do this? I have done something similar in Ruby before. I would make the column (Date in your case) unique at the database level then simply try inserting each record. When I get an exception thrown because the Date is not unique I would then proceed to update the QTY.
I found this article on mysql which says it supports multiple insert.
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
That statement is identical to the following two statements:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=3;
INSERT INTO table (a,b,c) VALUES (4,5,6)
ON DUPLICATE KEY UPDATE c=9;
So if we want to edit straight, we could do something like this.
INSERT INTO table (uniquekey,data) VALUES (1,2),(4,5)
ON DUPLICATE KEY UPDATE data=VALUES(data);