Toasobi
连续出现至少3次的数字
**
- 题目如下:
**
表:Logs
Column Name | Type |
---|---|
id | int |
num | varchar |
在 SQL 中,id 是该表的主键。
id 是一个自增列。
找出所有至少连续出现三次的数字。
返回的结果表中的数据可以按 任意顺序 排列。
结果格式如下面的例子所示:
示例 1:
输入:
Logs 表: | |
---|---|
id | num |
1 | 1 |
2 | 1 |
3 | 1 |
4 | 2 |
5 | 1 |
6 | 2 |
7 | 2 |
输出:
Result 表: |
---|
ConsecutiveNums |
1 |
解释:1 是唯一连续出现至少三次的数字。
解答:
官方解法:三表联查
连续出现的意味着相同数字的 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
;
Id Num Id Num Id Num
1 1 2 1 3 1
然后我们从上表中选择任意的 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
;
该题解不足之处:1.id不连续的连续数字无法查出 2.如果要求连续100次出现,直接就废了
方法二:对于官方解法id不连续的连续出现数字的补充解法
SELECT num AS ConsecutiveNums
FROM (
SELECT *,
@count := IF(@prev = num, @count + 1, 1) AS count,
@prev := num
FROM Logs, (SELECT @count := 0, @prev := NULL) AS vars
ORDER BY id
) AS tmp
WHERE count >= 3
GROUP BY num
思路:
1.首先,在内部查询中,我们使用了变量@count和@prev来跟踪数字的连续出现次数。我们还初始化了这两个变量,@count被设置为0,@prev被设置为NULL。
2.接下来,我们执行了一个外部查询,并从Logs表中检索数据。在这个查询中,我们使用@count和@prev变量来计算每个数字的连续出现次数。
3.在SELECT子句中,我们使用IF函数来判断当前数字(num)是否与前一个数字(@prev)相同。如果相同,@count加1;如果不同,@count重置为1。
4.我们还使用@prev := num来更新@prev变量,以便在下一次迭代中使用。
5.在ORDER BY子句中,我们按照id的顺序对结果进行排序。这是为了确保我们能够正确地识别连续出现的数字。
6.最后,在外部查询的SELECT语句中,我们选择连续出现次数(count)大于等于3的数字(num)作为结果。
7.为了消除重复的数字,我们使用GROUP BY子句对结果进行分组,以num作为分组依据。
方法三:使用窗口函数
select
distinct p.num as ConsecutiveNums
from(
select
id,
num,
lag(num,1)over(order by id) num1,
lag(num,2)over(order by id) num2
from
Logs
) p
where
p.num = p.num1 and p.num1 = p.num2
1.首先,在内部查询中,我们使用LAG函数来获取前两个数字(num1和num2),并将它们与当前数字(num)进行比较。LAG函数用于访问前面的行的数据。
2.在LAG函数中,我们通过指定order by id来定义排序的顺序,以确保我们按照id的顺序进行比较。
3.在外部查询中,我们选择满足条件的连续出现的数字(num = num1 = num2)作为结果。
4.我们使用DISTINCT关键字来消除重复的数字,并将它们作为结果返回。