MySQL 提供了几乎无穷无尽的方法来处理重复数据。大多数可以使用一句语句进行更新或删除。但是,有时必须发出多个命令才能完成工作。今天的文章将展示采用临时表和 SELECT DISTINCT 查询的解决方案。
MySQL 的永久与临时表L
注意,我们今天在这里创建的临时表与 MySQL 中的真正临时表不同,因为我们没有将 TEMPORARY 关键字添加到 CREATE TABLE 语句中。
在 MySQL 中,临时表是一种特殊类型的表,允许你存储临时结果集,你可以在单个会话中多次重复使用该表。当无法使用单个 SELECT 语句查询数据或耗用大量系统资源时,临时表就会派上用场。就像使用 TEMPORARY 关键字创建的临时表一样,我们的“临时”表将存储 SELECT 查询的即时结果,以便我们可以发出一个或多个其他查询来完全处理数据。然后,我们会使用临时表替换目标表。
从 amalgamated_actors 表中删除重复行
在“如何在 MySQL 中删除具有不同 ID 的重复行(第 3 部分)”文章中,我们成功删除了包含重复名的行。但是,仍然会留下 ID 和名相同的行,换句话说,即是整行都是重复的行。例如,我们可以在下面的结果集中看到“22 JENNIFER DAVIS” 出现了两次:
id | first_name | last_name | ||
--------------------------------------------------- | ||||
10 | PENELOPE | GUINESS | ||
14 | ED | CHASE | ||
22 | JENNIFER | DAVIS | ||
23 | JOHNNY | LOLLOBRIGIDA | ||
27 | BETTE | NICHOLSON | ||
34 | GRACE | MOSTEL | ||
41 | NICK | WAHLBERG | ||
39 | JOE | SWANK | ||
23 | CHRISTIAN | GABLE | ||
22 | JENNIFER | DAVIS |
这是使用临时表方法的理想例子。
MySQL 提供了特殊的 CREATE TABLE ... LIKE 命令,用于根据另一个表的定义创建一个空表,包含原本的表中定义的任何列属性和索引。
因此,我们可以基于 amalgamated_actors 表创建另一个表,如下所示:
-- Create temporary table
CREATE TABLE wp.temp_table LIKE wp.amalgamated_actors;
这是将 amalgamated_actors 表中的所有数据复制到 temp_table 的语句:
INSERT INTO wp.temp_table
SELECT DISTINCT * FROM wp.amalgamated_actors;
SELECT DISTINCT 子句是删除重复行的关键。
最后,我们需要重命名原本的表,以便我们可以用临时表替换它,并删除原本的表:
-- Rename and drop
RENAME TABLE wp.amalgamated_actors TO wp.old_amalgamated_actors,
wp.temp_table TO wp.amalgamated_actors;
DROP TABLE wp.old_amalgamated_actors;
现在 JENNIFER DAVIS 只有一行:
id | first_name | last_name | ||
--------------------------------------------------- | ||||
10 | PENELOPE | GUINESS | ||
14 | ED | CHASE | ||
22 | JENNIFER | DAVIS | ||
23 | JOHNNY | LOLLOBRIGIDA | ||
27 | BETTE | NICHOLSON | ||
34 | GRACE | MOSTEL | ||
41 | NICK | WAHLBERG | ||
39 | JOE | SWANK | ||
23 | CHRISTIAN | GABLE |
我们原本的 amalgamated_actors 表已经被“临时”表替换了。
使用 UNIQUE 约束删除重复行
在下一篇关于处理重复数据的文章中,我们将使用 UNIQUE 约束删除无论 ID 是否重复但具有重复名字段的行。