题目描述:
Write a SQL query to find all numbers that appear at least three times consecutively.
+----+-----+ | Id | Num | +----+-----+ | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | +----+-----+
For example, given the above Logs table, 1 is the only number that appears consecutively for at least three times.
题目大意:
编写一个SQL查询找出所有至少连续出现3次的数字。
例如,给定上面的Logs表,1是唯一至少连续出现3次的数字。
解题思路:
可以从题目Rank Scores(http://oj.leetcode.com/problems/rank-scores/)中获得启示
配合使用MySQL用户定义变量和聚组函数统计连续出现的数字个数
SQL语句:
# Write your MySQL query statement below
SELECT DISTINCT Num FROM (
SELECT Num, COUNT(Rank) AS Cnt FROM (
SELECT Num,
@curRank := @curRank + IF(@prevNum = Num, 0, 1) AS rank, @prevNum := Num
FROM Logs s, (SELECT @curRank := 0) r, (SELECT @prevNum := NULL) p
ORDER BY ID ASC
) t GROUP BY Rank HAVING Cnt >= 3
) n;
补充说明:
以题目描述的Logs表为例,上面的SQL语句中,最内层的SELECT语句执行结果如下:
+-----+------+-----------------+ | Num | rank | @prevNum := Num | +-----+------+-----------------+ | 1 | 1 | 1 | | 1 | 1 | 1 | | 1 | 1 | 1 | | 2 | 2 | 2 | | 1 | 3 | 1 | | 2 | 4 | 2 | | 2 | 4 | 2 | +-----+------+-----------------+
执行结果中的rank列将Num转化为从1开始递增的序号,但序号只在Num出现变化时增加,(连续出现的相同数字序号也相同)
第二层SELECT语句对rank进行计数,并只保留计数不小于3的条目,执行结果为:
+-----+-----+ | Num | Cnt | +-----+-----+ | 1 | 3 | +-----+-----+
最外层SELECT语句对Num进行去重。
本文链接:http://bookshadow.com/weblog/2015/01/14/leetcode-consecutive-numbers/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。
一帆风顺_好好加油 发布于 2015年1月23日 22:56 #
大神 这道题目 你的解析我没看懂 能否给代码一个详细的注释。。。谢谢了
在线疯狂 发布于 2015年1月24日 09:39 #
添加了补充说明,看看是否能明白?
一帆风顺_好好加油 发布于 2015年1月24日 16:18 #
看了,可以明白思路了 非常感谢大神的回复
jonny 发布于 2015年11月16日 13:46 #
太神了。。。。大神在哪高就,可否膜拜