LeetCode 196. 删除重复的电子邮箱

原题题目

表: Person

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| email       | varchar |
+-------------+---------+
id 是该表的主键列(具有唯一值的列)。
该表的每一行包含一封电子邮件。电子邮件将不包含大写字母。

编写解决方案 删除 所有重复的电子邮件,只保留一个具有最小 id 的唯一电子邮件。

(对于 SQL 用户,请注意你应该编写一个 DELETE 语句而不是 SELECT 语句。)

运行脚本后,显示的答案是 Person 表。驱动程序将首先编译并运行您的代码片段,然后再显示 Person 表。Person 表的最终顺序 无关紧要 。

返回结果格式如下示例所示。

示例 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。

方法一 分组

先对邮箱进行分组,然后查找邮箱最小id,形成一个子查询。

遍历表格,如果id不在子查询结果里,则删除。

注意:

1、这段代码在leetcode系统上可行,但是在本地运行中可能会报错1175,解决方法是解除安全模式,具体参考  MySQL报错之1175和1093-CSDN博客

2、这里在子查询外层再嵌套一个查询,因为不能同时对一个表执行子查询后再执行删除操作。否则会报错1093,具体参考  MySQL报错之1175和1093-CSDN博客

delete from Person where id not in
(select * from (select min(t1.id)
from Person as t1
group by t1.email) a);

方法二 窗口函数

用row_number(),按id升序,序号>1的就是重复且id较大的

注意事项与方法二一致

delete from Person
where id not in (
select id
from (select *,row_number() over(partition by email order by id) rowNumber
from Person) a
where rowNumber = 1
)

方法三 自连接

注意:在leetcode上成功运行,但是在本地mysql报错1175,解决方法是解除安全模式

DELETE p1 FROM Person p1,
    Person p2
WHERE
    p1.Email = p2.Email AND p1.Id > p2.Id

方法四 临时表实现分组

临时表解决安全模式(1175报错)和同时对一张表进行删除和查询操作(1093报错)

注意:此方法只能在本地mysql上运行,而在leetcode上执行报错

-- 第一步:创建临时表存储要删除的 id
CREATE TEMPORARY TABLE temp_to_delete (id INT);

-- 第二步:将要删除的 id 插入到临时表中
INSERT INTO temp_to_delete (id)
SELECT id
FROM Person
WHERE id NOT IN (
    SELECT MIN(id)
    FROM Person
    GROUP BY email
);

-- 第三步:使用临时表删除记录
DELETE FROM Person
WHERE id IN (SELECT id FROM temp_to_delete);

-- 第四步:删除临时表
DROP TEMPORARY TABLE temp_to_delete;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值