Mistakenly added duplicate records. How do I delete them? - mysql

EDIT
This query is not working, any idea why?
select `key`, distinct `filename`, `url`, `processed`, `timestamp` from snaps;
It says to check syntax near 'distinctfilename``
I have the following table
CREATE TABLE IF NOT EXISTS `snaps` (
`filename` varchar(255) COLLATE utf8_bin NOT NULL,
`url` text COLLATE utf8_bin NOT NULL,
`processed` int(11) NOT NULL,
`timestamp` int(11) NOT NULL,
KEY `key` (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
I exported the rows of the table and mistakenly imported it back into the same table. So now I have two rows of everything. filename is unique.
How can I delete the duplicate records?

SELECT DISTINCT into a temporary table, flush the first one, and move them back again.

If you have all the original unduplicated rows of the table, can you not just
TRUNCATE <table> and then reimport them?

Does second set of rows has an identical timestamp from the insert? If so, you could DELETE based on that timestamp.
Alternately, you could SELECT INTO OUTFILE, delete the last half, TRUNCATE TABLE and then LOAD DATA INFILE.

Related

I need to put in a script an id with zero value

CREATE TABLE IF NOT EXISTS home (
id int(11) NOT NULL AUTO_INCREMENT,
description(200) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
I need to insert a default value with id=0 but, I can't in this way. Anyone can help me?
You cannot have a DEFAULT value on an AUTOINCREMENT column. Also, as ID is your primary key, it would not really make sense to have a DEFAULT.
If you are just trying to insert an ID with a « 0 » value : mysql by default does not allow this on an AUTOINCREMENT field, but this can be tweaked with :
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
However this is not recommended. See the mysql docs
I would be very cautious about trying to do such a thing. MySQL is so adamant about keeping zeros out that it changes the values of 0 to 1 when a column becomes an auto-increment column. Consider what happens with this code:
CREATE TABLE IF NOT EXISTS home (
id int(11) NOT NULL,
description varchar(200) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1;
insert into home (id, description)
values (0, 'my home');
select *
from home;
alter table home modify column id int auto_increment;
select *
from home;
The table no longer has 0 after the alter table.
Presumably, this is because long ago MySQL decided that 0 is a signal for using the default value, so the value is baked in.
You can use any other value that you want. So you might consider -1 if you want a "default" values for your tables that use auto_increment.

Replace based on 2 columns

I have a table where I'd like to replace data based on 2 columns.
My query currently looks like this:
$query = "REPLACE INTO `".$database."`.`".$table_extras."` (`id`, `multiverseid`, `rulings`, `printings`, `foreignNames`) ";
$query .= "VALUES (".$cardCount.",
".$multiverseid.",
'".addslashes($rulings)."',
'".addslashes($printings)."',
'".addslashes($foreignNames)."');";
Currently with the above query things get replaced based on 'id'. How can I make it so it's replacing based on 'id' AND 'multiverseid'?
When I created my table it looked like the following:
CREATE TABLE IF NOT EXISTS `extras` (
`id` int(10) unsigned NOT NULL,
`multiverseid` int(10) unsigned NOT NULL,
`number` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`rulings` text COLLATE utf8_unicode_ci NOT NULL,
`printings` text COLLATE utf8_unicode_ci NOT NULL,
`foreignNames` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`, `number`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Create a unique index on id, multiverseid:
create unique index t_id_multiverseid on table_extras(id, multiverseid);
The only issue is the following. If id is already unique or a primary key, then it will continue to be used by the replace. You would need to drop this constraint.
It sounds like the table's primary key is "id". This makes it a little hard to parse your question :)
Perhaps your actual intention is to have a table with a primary key across both the id and the multiverseid columns, in which case your REPLACE would work as you require.
REPLACE INTO replaces based on the primary key or unique index.
Create a unique index on id and multiverseid:
create unique index table_extras_id_multiverseid on table_extras(id, multiverseid);
The documentation says:
if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.

Mysql - duplicate entry error for key with auto increment

Why do I get an error of the form:
Error in query: Duplicate entry '10' for key 1
...when doing an INSERT statement like:
INSERT INTO wp_abk_period (pricing_id, apartment_id) VALUES (13, 27)
...with 13 and 27 being valid id-s for existing pricing and apartment rows, and the table is defined as:
CREATE TABLE `wp_abk_period` (
`id` int(11) NOT NULL auto_increment,
`apartment_id` int(11) NOT NULL,
`pricing_id` int(11) NOT NULL,
`type` enum('available','booked','unavailable') collate utf8_unicode_ci default NULL,
`starts` datetime default NULL,
`ends` datetime default NULL,
`recur_type` enum('daily','weekly','monthly','yearly') collate utf8_unicode_ci default NULL,
`recur_every` char(3) collate utf8_unicode_ci default NULL,
`timedate_significance` char(4) collate utf8_unicode_ci default NULL,
`check_in_times` varchar(255) collate utf8_unicode_ci default NULL,
`check_out_times` varchar(255) collate utf8_unicode_ci default NULL,
PRIMARY KEY (`id`),
KEY `fk_period_apartment1_idx` (`apartment_id`),
KEY `fk_period_pricing1_idx` (`pricing_id`),
CONSTRAINT `fk_period_apartment1` FOREIGN KEY (`apartment_id`) REFERENCES `wp_abk_apartment` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_period_pricing1` FOREIGN KEY (`pricing_id`) REFERENCES `wp_abk_pricing` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Isn't key 1 id in this case and having it on auto_increment sufficient for being able to not specify it?
Note: If I just provide an unused value for id, like INSERT INTO wp_abk_period (id, pricing_id, apartment_id) VALUES (3333333, 13, 27) it works fine, but then again, it is set as auto_increment so I shouldn't need to do this!
Note 2: OK, this is a complete "twilight zone" moment: so after running the query above with the huge number for id, things started working normally, no more duplicate entry errors. Can someone explain me WTF was MySQL doing to produce this weird behavior?
It could be that your AUTO_INCREMENT value for the table and the actual values in id column have got out of whack.
This might help:
Step 1 - Get Max id from table
select max(id) from wp_abk_period
Step 2 - Align the AUTO_INCREMENT counter on table
ALTER TABLE wp_abk_period AUTO_INCREMENT = <value from step 1 + 100>;
Step 3 - Retry the insert
As for why the AUTO_INCREMENT has got out of whack I don't know. Added auto_increment after data was in the table? Altered the auto_increment value after data was inserted into the table?
Hope it helps.
I had the same problem and here is my solution :
My ID column had a bad parameter. It was Tinyint, and MySql want to write a 128th line.
Sometimes, your problem you think the bigger you have is only a tiny parameter...
Late to the party, but I just ran into this tonight - duplicate key '472817' and the provided answers didn't help.
On a whim I ran:
repair table wp_abk_period
which output
Number of rows changed from 472816 to 472817
Seems like mysql had the row count wrong, and the issue went away.
My environment:
mysql Ver 14.14 Distrib 5.1.73, for Win64 (unknown)
Create table syntax:
CREATE TABLE `env_events` (
`tableId` int(11) NOT NULL AUTO_INCREMENT,
`deviceId` varchar(50) DEFAULT NULL,
`timestamp` int(11) DEFAULT NULL,
`temperature` float DEFAULT NULL,
`humidity` float DEFAULT NULL,
`pressure` float DEFAULT NULL,
`motion` int(11) DEFAULT NULL,
PRIMARY KEY (`tableId`)
) ENGINE=MyISAM AUTO_INCREMENT=528521 DEFAULT CHARSET=latin1
You can check the current value of the auto_increment with the following command:
show table status
Then check the max value of the id and see if it looks right. If not change the auto_increment value of your table.
When debugging this problem check the table name case sensitivity (especially if you run MySql not on Windows).
E.g. if one script uses upper case to 'CREATE TABLE my_table' and another script tries to 'INSERT INTO MY_TABLE'. These 2 tables might have different contents and different file system locations which might lead to the described problem.

MySQL Update not updating any rows

This is a weird issue I'm having, I have a table and try to do a MySQL-Update query, however, PHPMyAdmin keeps saying 0 rows affected.
Table:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=55069 ;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `userid`, `name`, `last_login`) VALUES
(1, 55068, 'temp', '2012-02-02 09:04:50');
Query:
UPDATE `users` SET name='xorinzor' AND last_login=NOW() WHERE userid='55068'
No errors are returned, just nothing is happening, got no clue why that would be.
Regards,
Jorin
Change your update sentence to:
UPDATE `users` SET password='encryptedthingy', name='xorinzor', last_login=NOW()
WHERE userid=55068
Your SQL syntax was wrong. If you want to update multiple fields at once, you should not separate them with and keyword but with ,.
Also, make getting rid of single quotes for '55068' should help, since that column is a number. And '55068' is a string literal.
Make sure this sentence returns a value:
select * from `users` where userid=55068

Order by two fields - Indexing

So I've got a table with all users, and their values. And I want to order them after how much "money" they got. The problem is that they have money in two seperate fields: users.money and users.bank.
So this is my table structure:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(4) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(54) COLLATE utf8_swedish_ci NOT NULL,
`money` bigint(54) NOT NULL DEFAULT '10000',
`bank` bigint(54) NOT NULL DEFAULT '10000',
PRIMARY KEY (`id`),
KEY `users_all_money` (`money`,`bank`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci AUTO_INCREMENT=100 ;
And this is the query:
SELECT id, (money+bank) AS total FROM users FORCE INDEX (users_all_money) ORDER BY total DESC
Which works fine, but when I run EXPLAIN it shows "Using filesort", and I'm wondering if there is any way to optimize it?
Because you want to sort by a derived value (one that must be calculated for each row) MySQL can't use the index to help with the ordering.
The only solution that I can see would be to create an additional total_money or similar column and as you update money or bank update that value too. You could do this in your application code or it would be possible to do this in MySQL with triggers too if you wanted.