如何在 SQL 中删除重复行?

17 Mar 2025 | 6 分钟阅读

在本节中,我们将学习在 MySQL 和 Oracle 中删除重复行的不同方法。如果 SQL 表包含重复行,则必须删除重复行。

准备示例数据

脚本创建了一个名为 contacts 的表。

在上面的表中,我们插入了以下数据。

在执行 DELETE 语句后,我们执行脚本以重新创建测试数据。

查询返回 contacts 表中的数据


idfirst_namelast_name电子邮件年龄
7BenBarnes[email protected]21
13BrianBlessed[email protected]18
10ElizaBennett[email protected]23
1Kavin彼得森[email protected]22
14Kavin彼得森[email protected]23
8MischaBarton[email protected]20
11MichalKrane[email protected]17
4MichalJackson[email protected]18
2NickJonas[email protected]16
3彼得Heaven[email protected]25
12彼得Heaven[email protected]25
5SeanBean[email protected]20
9SeanBean[email protected]20
6TomBaker[email protected]30

以下 SQL 查询从 contacts 表返回重复的电子邮件


emailCOUNT(email)
[email protected]2
[email protected]2
[email protected]2

我们有三行具有 重复 的电子邮件。

(A) 使用 DELETE JOIN 语句删除重复行

输出

已经删除了三行。我们执行以下查询,以查找表中的 重复电子邮件

查询返回空集。要验证 contacts 表中的数据,请执行以下 SQL 查询


idfirst_namelast_name电子邮件年龄
7BenBarnes[email protected]21
13BrianBlessed[email protected]18
10ElizaBennett[email protected]23
1Kavin彼得森[email protected]22
8MischaBarton[email protected]20
11MichaKrane[email protected]17
4MichalJackson[email protected]18
2NickJonas[email protected]16
3彼得Heaven[email protected]25
5SeanBean[email protected]20
6TomBaker[email protected]30

id 为 9、12 和 14 的行已被删除。我们使用以下语句删除重复行

执行用于 创建 contacts 表的脚本。


idfirst_namelast_nameemail年龄
1BenBarnes[email protected]21
2Kavin彼得森[email protected]22
3BrianBlessed[email protected]18
4NickJonas[email protected]16
5MichalKrane[email protected]17
6ElizaBennett[email protected]23
7MichalJackson[email protected]18
8SeanBean[email protected]20
9MischaBarton[email protected]20
10彼得Heaven[email protected]25
11TomBaker[email protected]30

(B) 使用中间表删除重复行

要使用中间表删除重复行,请按照以下步骤操作:

步骤 1. 创建一个与实际表 结构 相同的新表

步骤 2. 从原始数据库表中插入不重复的行

步骤 3. 删除原始表,并将中间表重命名为原始表名。

例如,以下语句从 contacts 表中删除具有 重复 电子邮件的

(C) 使用 ROW_NUMBER() 函数删除重复行

注意:ROW_NUMBER() 函数自 MySQL 8.02 版本起支持,因此在使用该函数之前,应检查您的 MySQL 版本。

以下语句使用 ROW_NUMBER () 为每行分配一个连续的整数。如果电子邮件重复,则该行的编号将大于一。

以下 SQL 查询返回重复行的 id 列表

输出

id
9
12
14

删除 Oracle 中的重复记录

当我们发现表中有重复记录时,我们需要删除不必要的副本,以保持数据的清洁和唯一。如果一个表中有重复行,我们可以使用 DELETE 语句将其删除。

在这种情况下,我们有一个列,它不是用于 评估 表中 重复 记录的 的一部分。

考虑下表

VEGETABLE_IDVEGETABLE_NAMECOLOR
01Potato棕色
02Potato棕色
03洋葱红色
04洋葱红色
05洋葱红色
06南瓜绿色
07南瓜黄色



假设我们想保留具有最高 VEGETABLE_ID 的行,并删除所有其他副本。


MAX(VEGETABLE_ID)
2
5
6
7

我们使用 DELETE 语句来删除 VEGETABLE_ID 列 中的值不是 最高 的行。

已删除三行。


VEGETABLE_IDVEGETABLE_NAMECOLOR
02Potato棕色
05洋葱红色
06南瓜绿色
07黄色

如果想保留 id 最小的行,请使用 MIN() 函数而不是 MAX() 函数。

如果存在一个未参与评估重复项的列,则上述方法有效。如果所有列中的值都存在副本,则无法使用 VEGETABLE_ID 列。

让我们删除并用新结构重新创建 vegetable 表。



VEGETABLE_IDVEGETABLE_NAMECOLOR
01Potato棕色
01Potato棕色
02洋葱红色
02洋葱红色
02洋葱红色
03南瓜绿色
04南瓜黄色

在 vegetable 表中,VEGETABLE_ID、VEGETABLE_NAME 和 color 列中的值都已复制。

我们可以使用 rowid,它是一个指定 Oracle 存储行的定位器。因为 rowid 是唯一的,所以我们可以使用它来删除重复行。

查询验证删除操作


VEGETABLE_IDVEGETABLE_NAMECOLOR
01Potato棕色
02洋葱红色
03南瓜绿色
04南瓜黄色

下一个主题Nth Highest salary