題目地址:https://oj.leetcode.com/problems/consecutive-numbers/
這個(gè)題目是要求寫(xiě)一個(gè)sql,查詢(xún)出表中連續(xù)出現(xiàn)三次的記錄。表結(jié)構(gòu)非常簡(jiǎn)單如下:
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
這個(gè)Logs表里,只有Id和Num字段,而題目就是要找出連續(xù)出現(xiàn)3次的Num,對(duì)于這個(gè)表,答案就是1了。
思路很直觀暴力的一個(gè)想法就是Logs表自己關(guān)聯(lián)3次,關(guān)聯(lián)條件依次是Id+1,這樣就可以把連續(xù)記錄關(guān)聯(lián)出來(lái)了
我的代碼如下:
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)
這個(gè)題目雖然可以這樣解掉,但是很自然的會(huì)聯(lián)想,如果3變成n呢,題目變?yōu)榍筮B續(xù)出現(xiàn)n次的記錄,那該如何解?顯然暴力解法是不可行的。鑒于能力有限,我從discuss區(qū)找到了一個(gè)很贊的解法,通過(guò)定義變量,很巧妙的解了這個(gè)擴(kuò)展的問(wèn)題,原作者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
簡(jiǎn)單分析一下,作者通過(guò)定義兩個(gè)變量record和count來(lái)控制記錄和對(duì)應(yīng)的rank值,首先通過(guò)一個(gè)select @count:=0,@record:=(SELECT num from Logs limit 0,1)語(yǔ)句來(lái)初始化這兩個(gè)變量count=0,record=表里第一條記錄的num。接下來(lái)通過(guò)普通查詢(xún),將Logs表里每一條記錄查出來(lái),和record對(duì)比,如果相同,則count自增1,如果不同,那么新的record被賦值,同時(shí)count置1,很漂亮的自定義變量用sql實(shí)現(xiàn)了我們直覺(jué)上需要用邏輯代碼來(lái)完成的功能。而且這個(gè)代碼的一大優(yōu)勢(shì)是不需要用到Id字段~~非常棒
還有好的思路,請(qǐng)一定分享給我~~:)