自连接/窗口函数/having和where教程-180 连续出现的数字 182 重复电子邮箱

先来一个教程,having和where的区别到底在哪[面试被问到了]
SQL中having和where的区别
Group by与having/where的组合使用

where和having的区别:

  • where是行的过滤,having是分组结果的过滤
  • having必须和group by同时使用,where没有这个要求
  • 自连接/窗口函数/having和where教程-180 连续出现的数字 182 重复电子邮箱_第1张图片

    在这里插入图片描述

180 连续出现的数字

编写一个 SQL 查询,查找所有至少连续出现三次的数字。

+----+-----+
| Id | Num |
+----+-----+
| 1  |  1  |
| 2  |  1  |
| 3  |  1  |
| 4  |  2  |
| 5  |  1  |
| 6  |  2  |
| 7  |  2  |
+----+-----+
例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。

+-----------------+
| ConsecutiveNums |
+-----------------+
| 1               |
+-----------------+

题解1:

select distinct(num) as ConsecutiveNums
from (
	select num,(row_number() over(order by id )-row_number() over(partition by num order by id)) as rak_
	from Logs
) tmp
group by rak_,num
having count(rak_)>=3;

题解2:
思路:

  1. 由于要获取至少连续三次出现的数字,看到这个题肯定是会变的,如果是至少连续出现四次呢(100次呢),咱们连接四个表(连接一千个?)?这种方法肯定是不可取的。
  2. 找规律,找出这连续起来的数字有什么规律呢,我们会发现连续的数字是相同的数字,但是id有可能不是连续的,我们就需要通过对结果集进行再次编号,让其变成连续的。
    原始数据:
    自连接/窗口函数/having和where教程-180 连续出现的数字 182 重复电子邮箱_第2张图片
  3. 首先我们获取到对每条数据编号从1开始使用row_number()函数使用id来排序,即row_number() over(order by id)
select 
id,
num,
row_number() over (order by id) as orde

结果为:
自连接/窗口函数/having和where教程-180 连续出现的数字 182 重复电子邮箱_第3张图片

  1. 然后我们通过另一种方式排序将,这些num值一样的进行排序,然后对其编号同样使用row_bumber()使用num来分组使用id排序 over(partition by num order by id)
select 
id,
num,
row_number() over (partition by num order by id) as orde

结果为:
自连接/窗口函数/having和where教程-180 连续出现的数字 182 重复电子邮箱_第4张图片

  1. 通过3、4步骤我们能得到什么呢,两个相减之后我们可以得到,只要是相等的,则相减的值是一样的。而且如果不连续的话相减值也不一样。
select 
id,
num,
row_number() over(order by id)-row_number over()(partition by num order by id) as orde
from Logs

结果为:
自连接/窗口函数/having和where教程-180 连续出现的数字 182 重复电子邮箱_第5张图片
这样是不是一目了然呢,最后在通过num和orde两个共同分组找到一样的一共有几个,我们就可以找到连续的了。

select distinct Num as Consecutivenums
from(
select num,count(*) as num_count
from(
select id,
num,
row_number over(order by id)-row_number() over(partition by num order by id) as orde
from Logs) as W
group by num,orde) as S
where num_count >=3

结果为:

自连接/窗口函数/having和where教程-180 连续出现的数字 182 重复电子邮箱_第6张图片

182 寻找重复电子信箱

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

示例:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | [email protected] |
| 2  | [email protected] |
| 3  | [email protected] |
+----+---------+
根据以上输入,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| [email protected] |
+---------+
说明:所有电子邮箱都是小写字母。

题解:

select Email
from Person
group by Email
having count(Email)>1

你可能感兴趣的:(个人学习)