文章目录
  1. 1. 题目
  2. 2. 解题思路
  3. 3. 注意事项
  4. 4. 构造测试数据
  5. 5. 一种答案

题目

#180 Consecutive Numbers

解题思路

使用临时变量 prevVal 保存上一个 Num 值,然后使用临时变量 count 保存当前连续出现相同数字的次数。最外层 SELECT 再把 Num 这一列中 nowCount >= 3 的值取出。

连续数字计数可使用 @count := IF(@prevVal = Num, @count + 1, 1) 条件,prevVal 若为 NULL,等式不成立 count 初始化为 1;若 prevVal 是正常值则正常比较,现在值等于前值则加 1,否则初始化为 1。

这里如果用 CASE WHEN 则代码会长一些:

1
2
3
4
CASE
WHEN @prevVal = Num THEN @count:=@count + 1
ELSE @count:=1
END AS nowCount

注意事项

  • 刚开始没理解题目意思是要连续出现的数字,使用这样的查询结果答案是错误的 SELECT Num FROM Logs GROUP BY Num HAVING COUNT(Num) >= 3

    找方法判断这些数字是连续

  • 有一个测试案例是:某个数字连续出现 3 次,接着是其他数字,然后又连续出现三次。这时结果中这个数字会出现两次。

    加上 DISTINCT Num,相同数字只取一个

构造测试数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE Logs (
Id INT,
Num INT
);

-- 比题目中增加了一些容易出错的用例
INSERT INTO Logs VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 2),
(5, 1),
(6, 2),
(7, 2),
(8, 1),
(9, 1),
(10, 1);

预期结果:

Num
1

一种答案

1
2
3
4
5
6
7
8
9
10
11
12
-- Runtime: 1422 ms
SELECT DISTINCT
Num
FROM
(SELECT
Num,
@count:=IF(@prevVal = Num, @count + 1, 1) AS nowCount,
@prevVal:=Num
FROM
Logs, (SELECT @prevVal:=NULL) tmpVar) tmpTable
WHERE
nowCount >= 3

其中内层查询得到临时表 tmpTable 的语句为:

1
2
3
4
5
6
7
SELECT 
Num,
@count:=IF(@prevVal = Num, @count + 1, 1) AS nowCount,
@prevVal:=Num
FROM
Logs,
(SELECT @prevVal:=NULL) tmpVar

内层查询得到的结果为:

Num nowCount @prevVal:=Num
1 1 1
1 2 1
1 3 1
2 1 2
1 1 1
2 1 2
2 2 2
1 1 1
1 2 1
1 3 1

本博客微信公众号

文章目录
  1. 1. 题目
  2. 2. 解题思路
  3. 3. 注意事项
  4. 4. 构造测试数据
  5. 5. 一种答案