题目地址:https://oj.leetcode.com/problems/consecutive-numbers/
这个题目是要求写一个sql,查询出表中连续出现三次的记录。表结构非常简单如下:
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
这个Logs表里,只有Id和Num字段,而题目就是要找出连续出现3次的Num,对于这个表,答案就是1了。
思路很直观暴力的一个想法就是Logs表自己关联3次,关联条件依次是Id+1,这样就可以把连续记录关联出来了
我的代码如下:
select
distinct o1.Num
from(
select * from Logs
)o1
join(
select * from Logs
)o2
on(o1.Num=o2.Num and o1.Id=o2.Id+1)
join(
select * from Logs
)o3
on(o2.Num=o3.Num and o2.Id=o3.Id+1)
这个题目虽然可以这样解掉,但是很自然的会联想,如果3变成n呢,题目变为求连续出现n次的记录,那该如何解?显然暴力解法是不可行的。鉴于能力有限,我从discuss区找到了一个很赞的解法,通过定义变量,很巧妙的解了这个扩展的问题,原作者kent-huang
代码如下:
select DISTINCT num
FROM (
select
num,
case when @record = num then @count:=@count+1
when @record <> @record:=num then @count:=1
end as n
from Logs ,(
select
@count:=0,
@record:=(SELECT num from Logs limit 0,1)
) r
) a
where a.n>=3
简单分析一下,作者通过定义两个变量record和count来控制记录和对应的rank值,首先通过一个select @count:=0,@record:=(SELECT num from Logs limit 0,1)语句来初始化这两个变量count=0,record=表里第一条记录的num。接下来通过普通查询,将Logs表里每一条记录查出来,和record对比,如果相同,则count自增1,如果不同,那么新的record被赋值,同时count置1,很漂亮的自定义变量用sql实现了我们直觉上需要用逻辑代码来完成的功能。而且这个代码的一大优势是不需要用到Id字段~~非常棒
还有好的思路,请一定分享给我~~:)