1

我有一个只有一个主键列和一个文本列的表。文本列有重复的值,我希望它们消失。

我试过什么


我用谷歌搜索了一下,很快就找到了我认为的答案,那就是:

ALTER IGNORE TABLE tablename ADD UNIQUE INDEX index_name (column1);

但在尝试执行查询后,我最终得到 MySQL 说:“ #1062 - Duplicate entry 'v&d' for key 'remove_duplicates' ”。因此,在摆弄了一段时间后,我发现它不起作用。

之后我尝试创建一个 tmp 表并删除旧表,但我也无法做到这一点。我可能弄错了语法:

CREATE table `tmp` like `Tag`

alter table tmp add unique (text)

INSERT IGNORE INTO `tmp` SELECT * FROM `Tag`

RENAME TABLE `Tag` TO `deleteme`
RENAME TABLE `tmp` TO `Tag`

DROP TABLE `deleteme`;



我想要什么


列“文本”没有重复值的表。如果有人发现我以前的方法有任何错误,请告诉我,或者如果您认为应该/可以以不同的方式完成,请告诉我!



编辑


我忘了说我在PK上也有关系(是的,我知道很重要)。有没有办法“保留”与另一张桌子的关系?如果需要,我可以手动更改另一个表中的 id,但也可以更改它。

4

2 回答 2

10

当您插入表格时,请删除重复项:

CREATE table `tmp` like `Tag`

alter table tmp add unique (text)

INSERT INTO `tmp` SELECT min(pk), text FROM `Tag` group by text;

RENAME TABLE `Tag` TO `deleteme`
RENAME TABLE `tmp` TO `Tag`

DROP TABLE `deleteme`;
于 2013-08-20T14:44:17.063 回答
0

这就是我在一张相当大的桌子上做的方式我假设你有一个列“id”

ALTER TABLE Tag ADD UNIQUE INDEX text_id (text, id);

在 column1 上创建一个 UNIQUE INDEX。id 所以下一个查询应该运行得更快。

然后,如果您想知道表格标签中有多少重复项

SELECT COUNT(*) as "total" - COUNT(DISTINCT text) as "duplicates text" FROM Tag

要获得唯一的第一行,您应该运行(如果 FIFO 很重要)

INSERT INTO `tmp` SELECT MIN(id), text FROM `Tag` GROUP BY text (Gordon Linoff query)

要获得唯一的最后一行,您应该运行(如果 LIFO 很重要)

INSERT INTO `tmp` SELECT MAX(id), text FROM `Tag` GROUP BY text 

因为在覆盖索引之外复制应该很快,如果服务器不需要创建磁盘临时表......

RENAME TABLE `Tag` TO `deleteme`
RENAME TABLE `tmp` TO `Tag`

DROP TABLE `deleteme`;
于 2013-08-20T15:37:28.097 回答