连续出现三次的数字:LEAD 看后面两行
LeetCode 180 · LEAD/LAG、连续性判断
面试怎么回答
我用 LEAD(Num,1) 和 LEAD(Num,2) 按 Id 排序取后两行,三者相等就是连续三次,外层 DISTINCT 去重。更通用的连续问题我会用「行号减分组内行号」得到连续段编号,再按段计数,这样能处理任意连续 N 次,也不怕 Id 不连续。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
日志表按 Id 顺序记录了一串数字,找出所有至少连续出现三次的数字,每个数字只输出一次。
表结构
- Logs:Id(主键,自增)、Num
思路
用 LEAD 把下一行和下下一行的值拉到当前行,三个值相等就说明从这一行开始连续出现了三次。同一个数字可能连续出现四次、五次,会被判定多次,所以外层要 DISTINCT。
参考解法
select distinct Num ConsecutiveNums
from
(
select
Num,
lead(Num,1,null) over(order by id) n2,
lead(Num,2,null) over(order by id) n3
from Logs
)t1
where Num = n2 and Num = n3
易错点
- 忘了 DISTINCT,连续 4 次的数字会输出两遍。
- 这里依赖 Id 连续。如果 Id 有空洞(比如删过数据),「Id 相邻」不等于「记录相邻」,更稳妥的是按 ROW_NUMBER 重新编号,或者用「行号差值」的分组法。