题目描述
(通过次数171,917 | 提交次数252,097,通过率68.19%)
表:Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | email | varchar | +-------------+---------+ id是该表的主键列。 该表的每一行包含一封电子邮件。电子邮件将不包含大写字母。 编写一个 SQL 删除语句来 删除 所有重复的电子邮件,只保留一个id最小的唯一电子邮件。 以 任意顺序 返回结果表。(注意:仅需要写删除语句,将自动对剩余结果进行查询) 查询结果格式如下所示。 示例 1: 输入: Person 表: +----+------------------+ | id | email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | | 3 | john@example.com | +----+------------------+ 输出: +----+------------------+ | id | email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | +----+------------------+ 解释: john@example.com重复两次。我们保留最小的Id = 1。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/delete-duplicate-emails
//测试数据 Create table If Not Exists Person (Id int, Email varchar(255)); insert into Person (id, email) values ('1', 'john@example.com'); insert into Person (id, email) values ('2', 'bob@example.com'); insert into Person (id, email) values ('3', 'john@example.com');
解题思路
这是一道关于delete操作题目。
对于MySQL数据库来说,学习delete操作,看这一篇就够了。
Person表中主键为id,但存在多个id对应同一个email的情况。题目要求:相同的email,只保留一条记录,即id值最小的那条。
那么,可以通过如下步骤来实现:
**第一步**:得出每个email对应的最小id;
**第二步**:删除除第一步结果中id值的其他所有行;
对于第一步,是一个分组取最小值的典型操作,使用group by + min函数或者开窗函数,都可以很简单的实现。
对于第二步,首先是个删除操作,那么就需要使用delete关键字。然后使用排除操作,把需要的行留下,不需要的行删除即可。
在sql语言中,排除操作可以使用not in或not exists来完成。可以参考下面的方法一和方法二。
这里,强哥比较推荐第三种方法:自关联。
首先,使用自关联对email相同的行两两组合;然后,使用比较运算符把大于待删除表中id的值的行全部删除。这种方法,在表中数据量较大时,有较好的性能表现。详细写法可以参考下面的方法三。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
--方法一 delete from Person where id not in ( select * from ( select min(b.id) from Person b group by b.email ) as a ); --方法二 delete from Person as a where not exists ( select 1 from ( select min(b.id) as min_id from Person b group by b.email ) as c where a.id = c.min_id ); --方法三 delete a from Person as a inner join Person as b on a.email = b.email and a.id > b.id;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。