原题
编写一个 SQL 查询,查找所有至少连续出现三次的数字。
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
例如,给定上面的 Logs
表, 1 是唯一连续出现至少三次的数字。
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/consecutive-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解1
方法:用 DISTINCT
和 WHERE
语句
连续出现的意味着相同数字的 Id 是连着的,由于这题问的是至少连续出现 3 次,我们使用 Logs
并检查是否有 3 个连续的相同数字。
SELECT *
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
;
然后我们从上表中选择任意的 Num 获得想要的答案。同时我们需要添加关键字 DISTINCT
,因为如果一个数字连续出现超过 3 次,会返回重复元素。
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
;
题解2
窗口函数lead()
完美解决
使用窗口函数的偏差函数完美实现。 可以这样理解:将num复制两列num1和num2,然后num1整体向上移动一行,num2整体向上移动两行,如下 :
所以只要num=num1=num2即可.
# Write your MySQL query statement below
select distinct num as ConsecutiveNums from
(
select num,lead(num,1)over()as num1,lead(num,2)over()as num2
from logs
) as c
where c.num = c.num1 and c.num1 = c.num2
题解3
使用变量,不用连多个表,降低时间空间复杂度
pre记录前一个数的值,count,nums记录前一个数的出现次数
IF()表达式用法
select
distinct num as ConsecutiveNums
from
(
select
num,
if(@pre=num,@count:=@count+1,@count:=1) as nums,
@pre:=num
from logs as l,
(select @pre:=null,@count:=1)as pc
) as n
where nums>=3