MySQL,如何合并表重复条目

时间:2012-10-04 12:47:58

标签: mysql sql myisam

  

可能重复:
  How can I remove duplicate rows?
  Remove duplicates using only a MySQL query?

我有一张大表,有大约14M条目。表类型是MyISAM而不是InnoDB。

不幸的是,我在这个表中有一些重复的条目,我发现了以下请求:

SELECT device_serial, temp, tstamp, COUNT(*) c FROM up_logs GROUP BY device_serial, temp, tstamp HAVING c > 1

为了避免将来出现这些重复,我想使用SQL请求将当前索引转换为唯一约束:

ALTER TABLE  up_logs DROP INDEX UK_UP_LOGS_TSTAMP_DEVICE_SERIAL,
ALTER TABLE up_logs ADD INDEX UK_UP_LOGS_TSTAMP_DEVICE_SERIAL (  `tstamp` ,  `device_serial` )

但在此之前,我需要清理我的副本!

我的问题是:如何只保留一个重复条目的条目?请记住,我的表包含14M条目,因此如果可能的话,我希望避免循环。

欢迎任何评论!

3 个答案:

答案 0 :(得分:4)

在您需要具有唯一身份的列上创建新的唯一键会自动清除任何重复项的表。

ALTER IGNORE TABLE `table_name`
    ADD UNIQUE KEY `key_name`(`column_1`,`column_2`);

IGNORE 部分不允许脚本在发生第一个错误后终止。默认行为是删除重复项。

答案 1 :(得分:4)

由于MySQL允许在更新/删除语句中使用子查询,但是如果它们引用了您要更新的表,那么我将首先创建原始表的副本。然后:

DELETE FROM original_table 
WHERE id NOT IN( 
    SELECT id FROM copy_table 
    GROUP BY column1, column2, ...
);

但是我可以想象复制一个包含14M条目的表需要一些时间...选择要在复制时保留的项目可能会更快:

INSERT INTO copy_table 
    SELECT * FROM original_table 
    GROUP BY column1, column2, ...;

然后

DELETE FROM original_table 
WHERE id IN(
    SELECT id FROM copy_table
);

自从我上次使用MySQL和SQL以来已经有一段时间了,所以我确信有一些性能更好的东西 - 但这应该有效;)

答案 2 :(得分:1)

这是你删除重复行的方法......我会写你的例子,你需要申请你的代码。我有ID的Actors表,我想删除重复first_name

的行
mysql> select actor_id, first_name from actor_2;
+----------+-------------+
| actor_id | first_name  |
+----------+-------------+
|        1 | PENELOPE    |
|        2 | NICK        |
|        3 | ED          |
....
|      199 | JULIA       |
|      200 | THORA       |
+----------+-------------+

200 rows in set (0.00 sec)

- 如果下一行具有相同的first_name,则使用名为@a的变量来获取ID(重复,如果不是,则返回null)。

mysql> select if(first_name=@a,actor_id,null) as first_names,@a:=first_name from actor_2 order by first_name;
+---------------+----------------+
|  first_names  | @a:=first_name |
+---------------+----------------+
|          NULL | ADAM           |
|            71 | ADAM           |
|          NULL | AL             |
|          NULL | ALAN           |
|          NULL | ALBERT         |
|           125 | ALBERT         |
|          NULL | ALEC           |
|          NULL | ANGELA         |
|           144 | ANGELA         |
...
|          NULL | WILL           |
|          NULL | WILLIAM        |
|          NULL | WOODY          |
|            28 | WOODY          |
|          NULL | ZERO           |
+---------------+----------------+
200 rows in set (0.00 sec)

- 我们只能获得重复的ID:

    mysql> select first_names from (select if(first_name=@a,actor_id,null) as first_names,@a:=first_name from actor_2 order by first_name) as t1;
    +-------------+
    | first_names |
    +-------------+
    |        NULL |
    |          71 |
    |        NULL |
     ...
    |          28 |
    |        NULL |
    +-------------+
    200 rows in set (0.00 sec)

- 最后一步,让我们删除!

mysql> delete from actor_2 where actor_id in (select first_names from (select if(first_name=@a,actor_id,null) as first_names,@a:=first_name from actor_2 order by first_name) as t1);
Query OK, 72 rows affected (0.01 sec)

- 让我们查看我们的表格:

mysql> select count(*) from actor_2 group by first_name;
+----------+
| count(*) |
+----------+
|        1 |
|        1 |
|        1 |
...
|        1 |
+----------+
128 rows in set (0.00 sec)

它有效,如果您有任何问题请写回来