删除 MySQL 中的重复行

Sweety Rupani 2024年2月15日
  1. 使用 DELETE JOIN 语句删除重复行
  2. 使用嵌套查询删除重复行
  3. 使用临时表删除重复行
  4. 使用 ROW_NUMBER() 函数删除重复行
删除 MySQL 中的重复行

本文将向你展示在 MySQL 中删除表中存在的重复行的多种方法。有四种不同的方法来完成这项任务。

  1. 使用 DELETE JOIN 语句删除重复行
  2. 使用嵌套查询删除重复行
  3. 使用临时表删除重复行
  4. 使用 ROW_NUMBER() 函数删除重复行

以下脚本创建一个包含四列(custid、first_name、last_name 和 email)的表 customers

CREATE TABLE customers (custid INT,  first_name VARCHAR(50) NOT NULL,  last_name  VARCHAR(50) NOT NULL,  email VARCHAR(255) NOT NULL );
CREATE TABLE customers (custid INT,  first_name VARCHAR(50) NOT NULL,  last_name  VARCHAR(50) NOT NULL,  email VARCHAR(255) NOT NULL );

将示例数据值插入 customers 表以进行演示。

INSERT INTO customers  
VALUES (110,'Susane','Mathew','sussane.mathew@gmail.com'),
       (124,'Jean','Carl','jean.carl@gmail.com'),
       (331,'Peter','cohelo','peter.coh@google.com'),
       (114,'Jaine','Lora','jaine.l@abs.com'),
       (244,'Junas','sen','jonas.sen@mac.com');

INSERT INTO customers  
VALUES (113,'Jaine','Lora','jaine.l@abs.com'),
       (111,'Susane','Mathew','sussane.mathew@gmail.com'),
       (665,'Roma','Shetty','roma.sh11@yahoo.com'),
       (997,'Beatrice','shelon','beatrice.ss22@yahoo.com'),
       (332,'Peter','cohelo','peter.coh@google.com');
注意
你可以使用它在删除后再次插入值。

下面是从 customers 表返回所有数据的给定查询:

SELECT * FROM customers order by custid;

删除 mysql 中的重复行 - 示例

为了从表中查找重复记录,我们将在 customers 表中执行下面提到的查询。

SELECT custid, COUNT(custid) FROM customers GROUP BY  custid HAVING  COUNT(custid) > 1; 

如你所见,我们的结果中有三行具有重复的客户 ID。

使用 DELETE JOIN 语句删除重复行

使用 INNER JOINdelete statement 允许你从 MySQL 的表中删除重复的行。

以下查询通过选择具有最低客户 ID 的重复记录的所有行来使用嵌套查询的概念。找到后,我们将删除这些具有最低 custid 的重复记录:

Delete from customers where custid IN (Select c1.custid FROM customers as c1
INNER JOIN customers as c2 ON c1.custid < c2.custid AND c1.email = c2.email);

在这个查询中客户表被引用了两次;因此,它使用别名 c1 和 c2。

输出将是:

删除 mysql 中的重复行-删除连接

它表示已删除三行。

SELECT custid, COUNT(custid) FROM customers GROUP BY  custid HAVING  COUNT(custid) > 1; 

现在,此查询返回一个空集,这意味着重复的行已被删除。

我们可以使用 select 查询来验证 customers 表中的数据:

SELECT * FROM customers;

如果你希望删除重复的行并保留最低的 custid,那么你可以使用相同的查询,但条件略有不同,如以下语句所示:

Delete from customers where custid IN (Select c1.custid FROM customers as c1
INNER JOIN customers as c2 ON c1.custid > c2.custid AND c1.email = c2.email);

以下输出显示了删除重复行后 customers 表的数据。

删除 mysql 中的重复行 - 删除连接删除条目

使用嵌套查询删除重复行

现在让我们看一下使用嵌套查询删除重复行的分步过程。这是解决问题的一种比较直接的方法。

首先,我们将使用此查询从表中选择唯一记录。

Select * from (select max(custid) from customers group by email);

然后我们将使用带有 where 子句的 delete 查询,如下所示,删除表中的重复行。

Delete from customers where custid not in 
    (select * from (select max(custid) from customers group by email));

输出将是:

删除 mysql 中的重复行-嵌套查询

使用临时表删除重复行

现在让我们看一下使用临时表删除重复行的分步过程:

  1. 首先,你需要创建一个与原表结构相同的新表。
  2. 现在,将原始表中的不同行插入到临时表中。
  3. 删除原表,将临时表重命名为原表。

第 1 步:使用 CREATE TABLELIKE 关键字创建表

复制整个表结构的语法如下所示。

CREATE TABLE destination_table LIKE source;

因此,假设我们有相同的客户表,我们将编写下面给出的查询。

CREATE TABLE temporary LIKE customers;

步骤 2. 在临时表中插入行

下面给出的查询从客户复制唯一行并将其写入临时表。在这里,我们按电子邮件分组。

INSERT INTO temporary SELECT * FROM customers GROUP BY email; 

步骤 3. 删除原始客户表并通过将其重命名为客户来创建一个临时表作为原始表。

DROP TABLE customers;

ALTER TABLE temporary RENAME TO customers;

输出将是:

删除 mysql 中的重复行-临时表

这种方法很耗时,因为它需要更改表的结构,而不仅仅是处理数据值。

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

ROW_NUMBER() 函数已在 MySQL 8.02 版中引入。因此,如果你运行的是高于 8.02 的 MySQL 版本,则可以采用这种方法。

此查询使用 ROW_NUMBER() 函数为每一行分配一个数值。在重复电子邮件的情况下,行号将大于一。

SELECT  custid, email, ROW_NUMBER() OVER ( PARTITION BY email ORDER BY email ) AS row FROM customers;

上面的代码片段返回重复行的 id 列表:

SELECT custid
FROM ( SELECT custid, ROW_NUMBER() OVER (PARTITION BY email ORDER BY email) AS row FROM customers) t WHERE row > 1;

一旦我们获得具有重复值的客户列表,我们可以使用 delete 语句在 where 子句中使用子查询删除它,如下所示。

DELETE FROM customers
WHERE custid IN 
(SELECT custid  FROM 
     (SELECT custid, ROW_NUMBER() OVER
                (PARTITION BY email ORDER BY email) AS row FROM customers) t
                      WHERE row > 1);

输出将是:

删除 mysql 中的重复行——行号函数