力扣刷题学习SQL篇——1-6 删除(删除重复的电子邮箱——中间表实现/连表实现)
1、题目
题目链接:https://leetcode.cn/problems/delete-duplicate-emails/submissions/
SQL架构
Create table If Not Exists Person (Id int, Email varchar(255))
Truncate table Person
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')
表: 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。
2、官方解法:连表实现
首先把表自连起来,然后email相等的时候连起来,取出p1.id>p2.id的数据删掉
注意一下,这里有点要注意的,delete p1 from 开头因为这个删除的表要说明,如果只有一个表的情况下可以省略
DELETE p1 from Person p1 ,Person p2 where p1.email = p2.email and p1.id > p2.id
3、更快的解法,临时表实现
上面的解法要连表生成新的表,这里其实不是很好,当数据量很大的时候生成的这个表会很巨大。
那么我们可以通过另一种思路来解决这个问题,如果我们能先一步获取到这个id是不是就能解决问题呢?就不需要连表了呀
一个错误的示范,报错为You can’t specify target table ‘Person’ for update in FROM clause,您不能在FROM子句中为更新指定目标表“Person”。这应该是锁的问题,delete已经锁定了person这个表,但是你括号里面的获取的新列针对的也是person表,那么就产生了问题了。
DELETE from Person where id not in
(SELECT min(id) id from Person group by email)
解决办法:中转一下,创建一个临时表,借用这个临时表达到不同表的目的来实现。这里我们针对的是person表和临时表s,这样就不会有问题了
DELETE from Person where id not in
(
SELECT id from
(SELECT min(id) id from Person group by email) s
)
update Salary set sex = char(ascii('m')+ascii('f') - ascii(sex))
4、一些拓展
如果你不记得如何删除语句的,就看这里吧
SQL DELETE 语句
https://www.runoob.com/sql/sql-delete.html
DELETE FROM table_name
WHERE some_column=some_value;