Leetcode 解题记录【数据库篇】180. 连续出现的数字

180. 连续出现的数字

题目描述

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

+----+-----+
| Id | Num |
+----+-----+
| 1  |  1  |
| 2  |  1  |
| 3  |  1  |
| 4  |  2  |
| 5  |  1  |
| 6  |  2  |
| 7  |  2  |
+----+-----+

例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。

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

此题解法较多,这里主要分享三种解法。

解法一

可以给连续出现的数字一个编号,然后再选择编号大于2的数字,最后再给这些数字distinct 一下。重点在于如何给连续出现的数字一个编号。这里可以考虑定义两个变量@c_rank@p_value。其中c_rank存连续出现的数字的编号,初始化为0p_value存前一行记录的数字,初始化为NULL。在遍历Logs 表时,如果当前行的数字与前一行的数字相同,则连续出现,需将c_rank + 1,否则p_value赋值为当前行的数字,c_rank赋值为1
参考SQL(MySQL v5.6)如下:

set @p_value := NULL, @c_rank := 0;
select
L1.Id, L1.Num,
case
when @p_value = L1.Num then @c_rank := @c_rank + 1
when @p_value := L1.Num then @c_rank := 1
end as `Rank`
from Logs L1

执行结果如下

IdNumRank
111
212
313
421
511
621
722

最后再选择Rank值大于2的数字distinct 一下。该解法的好处是,不需要Id值连续。

解法二

由于题目中Id值连续连续,可以在遍历每一行记录时检查前面两行记录的数字是不是相等。最后再distinct 一下。
参考SQL(MySQL v5.6)如下:

select distinct(L4.Num) as ConsecutiveNums
from(
  select L1.Num
  from `Logs` L1
  where L1.Num = (select L2.Num from `Logs` L2 where L2.Id = L1.Id - 1)
  and L1.Num = (select L3.Num from `Logs` L3 where L3.Id = L1.Id - 2)
) as L4

解法三

使用连接,其实这种方法和方法二有很大相似之处(相关子查询,内部一般转化会为连接)。
参考SQL(MySQL v5.6)如下:

SELECT DISTINCT
    L1.Num AS ConsecutiveNums
FROM
    Logs L1,
    Logs L2,
    Logs L3
WHERE
    L1.Id = L2.Id - 1
    AND L2.Id = L3.Id - 1
    AND L1.Num = L2.Num
    AND L2.Num = L3.Num
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值