題目地址: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字段~~非常棒
還有好的思路,請一定分享給我~~:)