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字段~~非常棒

 

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



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。