如何在MySQL中删除重复的行
简介:在本教程中,您将学习在MySQL中删除重复行的各种方法。
在上一教程中,我们向您展示了如何在表中查找重复值。
识别重复的行后,您可能需要删除它们以清理数据。
准备样本数据
以下脚本创建表联系人,并将示例数据插入到联系人表中进行演示。
DROP TABLE IF EXISTS contacts; CREATE TABLE contacts ( id INT PRIMARY KEY AUTO_INCREMENT, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, email VARCHAR(255) NOT NULL ); INSERT INTO contacts (first_name,last_name,email) VALUES ('Carine ','Schmitt','[email protected]'), ('Jean','King','[email protected]'), ('Peter','Ferguson','[email protected]'), ('Janine ','Labrune','[email protected]'), ('Jonas ','Bergulfsen','[email protected]'), ('Janine ','Labrune','[email protected]'), ('Susan','Nelson','[email protected]'), ('Zbyszek ','Piestrzeniewicz','[email protected]'), ('Roland','Keitel','[email protected]'), ('Julie','Murphy','[email protected]'), ('Kwai','Lee','[email protected]'), ('Jean','King','[email protected]'), ('Susan','Nelson','[email protected]'), ('Roland','Keitel','[email protected]');
请注意,您可以在执行DELETE语句后执行此脚本来重新创建测试数据。
此查询从联系人表返回数据:
SELECT * FROM contacts ORDER BY email;
以下查询返回联系人表中的重复电子邮件:
SELECT email, COUNT(email) FROM contacts GROUP BY email HAVING COUNT(email) > 1;
如您所见,我们有四行重复的电子邮件。
A)使用DELETE JOIN语句删除重复的行
MySQL为您提供了DELETE JOIN语句,使您可以快速删除重复的行。
以下语句删除重复的行并保留最高的ID:
DELETE t1 FROM contacts t1 INNER JOIN contacts t2 WHERE t1.id < t2.id AND t1.email = t2.email;
该查询两次引用联系人表,因此,它使用表别名t1和t2。
输出为:
Query OK, 4 rows affected (0.10 sec)
它表示已删除四行。
您可以执行再次查找重复电子邮件的查询以验证删除:
SELECT email, COUNT(email) FROM contacts GROUP BY email HAVING COUNT(email) > 1;
查询返回一个空集,这意味着重复的行已被删除。
我们来验证来自联系人表的数据:
SELECT * FROM contacts;
ID为2、4、7和9的行已删除。
如果要删除重复的行并保留最低的ID,可以使用以下语句:
DELETE c1 FROM contacts c1 INNER JOIN contacts c2 WHERE c1.id > c2.id AND c1.email = c2.email;
请注意,您可以再次执行用于创建联系人表的脚本并测试此查询。
以下输出显示了删除重复的行之后的联系人表数据。
B)使用中间表删除重复的行
下面显示了使用中间表删除重复行的步骤:
创建一个新表,其结构与要删除重复行的原始表相同。
从原始表插入不同的行到立即表。
删除原始表,然后将立即表重命名为原始表。
以下查询说明了步骤:
步骤1.创建一个新表,其结构与原始表相同:
CREATE TABLE source_copy LIKE source;
步骤2.将不同的行从原始表插入到新表中:
INSERT INTO source_copy SELECT * FROM source GROUP BY col; -- column that has duplicate values
步骤3.删除原始表并将立即表重命名为原始表
DROP TABLE source; ALTER TABLE source_copy RENAME TO source;
例如,以下语句从联系人表中删除具有重复电子邮件的行:
-- step 1 CREATE TABLE contacts_temp LIKE contacts; -- step 2 INSERT INTO contacts_temp SELECT * FROM contacts GROUP BY email; -- step 3 DROP TABLE contacts; ALTER TABLE contacts_temp RENAME TO contacts;
C)使用ROW_NUMBER()函数删除重复的行
请注意,自MySQL 8.02版以来,已支持ROW_NUMBER()函数,因此您应在使用该函数之前检查MySQL版本。
以下语句使用ROW_NUMBER()函数为每行分配一个连续的整数。
如果电子邮件重复,则行号将大于一。
SELECT id, email, ROW_NUMBER() OVER ( PARTITION BY email ORDER BY email ) AS row_num FROM contacts;
以下语句返回重复行的id列表:
SELECT id FROM ( SELECT id, ROW_NUMBER() OVER ( PARTITION BY email ORDER BY email) AS row_num FROM contacts ) t WHERE row_num > 1;
您只需使用带有WHERE子句中的子查询的DELETE语句从联系人表中删除重复的行:
DELETE FROM contacts WHERE id IN ( SELECT id FROM ( SELECT id, ROW_NUMBER() OVER ( PARTITION BY email ORDER BY email) AS row_num FROM contacts ) t WHERE row_num > 1 );
MySQL发出以下消息:
4 row(s) affected
在本教程中,您学习了如何使用DELETE JOIN语句或中间表在MySQL中删除重复的行。