Leetcode-Database-180-Consecutive Numbers-Medium

Leetcode-Database-180-Consecutive Numbers-Medium

题目地址: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表里,只有IdNum字段,而题目就是要找出连续出现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

 

简单分析一下,作者通过定义两个变量recordcount来控制记录和对应的rank值,首先通过一个select @count:=0,@record:=(SELECT num from Logs limit 0,1)语句来初始化这两个变量count=0record=表里第一条记录的num。接下来通过普通查询,将Logs表里每一条记录查出来,和record对比,如果相同,则count自增1,如果不同,那么新的record被赋值,同时count1,很漂亮的自定义变量用sql实现了我们直觉上需要用逻辑代码来完成的功能。而且这个代码的一大优势是不需要用到Id字段~~非常棒

 

还有好的思路,请一定分享给我~~:)



你可能感兴趣的:(Leetcode-Database-180-Consecutive Numbers-Medium)