Navicat 博客

2018 年 1 月 16 日,由 Robert Gravelle 撰写

大多数重复记录属于这两类:重复含义和非唯一键。“如何在 MySQL 中发现和删除具有重复含义的值”文章处理了重复含义的记录。而后续文章 讨论了如何识别非唯一键。这是在同一个表中的两条记录具有相同的键,但可能有或可能没有不同的值和含义。今天的文章将介绍如何删除具有重复数据但具有不同键的行。

按类型识别重复项

在“如何识别具有非唯一键的重复项”文章中显示的最后一个查询以易于查看的格式列出了所有重复项:

Repetitions     row_data
----------------------------------------------------------------
2 22 (DAVIS, JENNIFER) | 22 (DAVIS, JENNIFER)
2 23 (LOLLOBRIGIDA, JOHNNY) | 23 (GABLE, CHRISTIAN)
2 41 (WAHLBERG, NICK) | 12 (WAHLBERG, NICK)

确定了所有重复的键和值后,我们就可以决定如何以最佳方式处理冗余数据。

JENNIFER DAVIS 出现在两条记录中,具有相同的键 22,使这些行完全重复。NICK WALBERG 的名字段是重复的,但 ID 不是。还有另一个重复的键 #23,是两条不相关的演员的记录:“JOHNNY LOLLOBRIGIDA”和“CHRISTIAN GABLE”。关于 22 和 23 的重复键,第一个是真正的重复,而第二个只需要为其中一条记录生成新键就可解决。

使用 DELETE JOIN 删除行

在“如何在 MySQL 中发现和删除具有重复含义的值”文章中,我们通过对执行搜索和替换值来从 SELEC T结果集中删除重复项。在这里,我们将使用 DELETE JOIN 语句永久删除其中一个重复的行。

由于我们正在比较同一个表中的字段,因此我们必须将表连接到自身。我们可以在 WHERE子句中比较 id 来选择保留较小或较大的 id 号。以下语句保留最大的 id:

DELETE a FROM wp.amalgamated_actors a
  INNER JOIN wp.amalgamated_actors a2
WHERE a.id < a2.id
AND   a.first_name = a2.first_name
AND   a.last_name  = a2.last_name;

1 row(s) affected	0.093 sec

在这种情况下,受影响(已删除)的行是 id 为 12 的 NICK WAHLBERG。快速的 SELECT 语句可确认结果:

id     first_name     last_name
-------------------------------------
10 PENELOPE GUINESS
12 NICK WAHLBERG
14 ED CHASE
22 JENNIFER DAVIS
23 JOHNNY LOLLOBRIGIDA
27 BETTE NICHOLSON
34 GRACE MOSTEL
39 JOE SWANK
23 CHRISTIAN GABLE
22 JENNIFER DAVIS

如果你想保留最小的 id,你只需将 a.id < a2.id 表达式更改为 a.id > a2.id

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

删除具有非唯一键的行

对于 id 为 22 的 JENNIFER DAVIS 出现两次的情况,我们需要采用不同的方法。因为使用 a.id = a2.id 运行上述语句将针对表中的每一行!原因是我们实质上每一行与自身匹配!在下一篇文章中,我们将学习如何删除像这样具有非唯一键的行。

Navicat 文章
频道条目
分享
文章归档