此为 LeetCode 上 2021-11-07 的每日一题:【182. 查找重复的电子邮箱

1.题目描述

编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。

示例:

1
2
3
4
5
Create table If Not Exists Person (id int, email varchar(255))
Truncate table Person
insert into Person (id, email) values ('1', 'a@b.com')
insert into Person (id, email) values ('2', 'c@d.com')
insert into Person (id, email) values ('3', 'a@b.com')
+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+

根据以上输入,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+

说明:所有电子邮箱都是小写字母。


2.题解

【解法一】:借助HAVING语句+聚合函数

1
2
3
4
select Email
from Person
group by Email
having count(Email)>1;

使用 group by 对Email分组,
然后 having 用于分组后的过滤,
其中 count(Email) 对其计数。

having 和 where的区别,where的执行在分组前,having在分组后

【解法二】:自连接

1
2
3
select DISTINCT P1.Email 
from Person p1, Person p2
where p1.Email = p2.Email and p1.Id != p2.Id;

1
2
3
4
select distinct p1.email 
from Person p1 join Person p2
on p1.Email = p2.Email
where p1.Id != p2.Id;

【解法三】:子表查询

1
2
3
4
5
6
7
8
9
10
11
-- 先计数,再查询
SELECT
Email
FROM
(
SELECT Email, count(*) num
FROM Person
GROUP BY Email
) t1
WHERE
num > 1;

题外问答:SQL语句一定要大写吗?

不用非写成大写,SQL语句对大小写不敏感。但是,编译的时候,操作系统会将所有字符转换成大写的,再进行编译。如果大写,在编译的时候,可以节省转化的时间。当SQL语句大量的时候,就显得很重要了。在大型的ERP系统开发的时候,往往会这么要求。