180. Consecutive Numbers 连续登录n次的用户
虽然题目很简短,但是很难做啊!属于比较经典的题目,记录一下思路。
参考链接:https://leetcode.cn/problems/consecutive-numbers/solutions/21537/sql-server-jie-fa-by-neilsons
row_number() over([partition by value_expression,...n] order by columnName)
题目解析:
1. 要获取至少连续出现三次的数字,不能强力破解,三个表join,如果出现一百次呢?
2. 寻找连续相同num数字,但是id在实际工作过程中可能是不连续的,比如某一次操作删除了某些数据。这样我们可能就需要对结果集合编号,使其变成连续的。
原始数据:(这里我们也考虑了可能)
解题过程:
1. 对于原始数据编号,从1开始使用row_number() over(expresion)函数,使用id来排序。
SELECT id, num, row_number() over(order by id) as SerialNum FROM ContinueNumber
运行结果为:
2. 使用原始数据另一维度排序,这些num值一样的分组排序,然后对其编号同样使用row_number() over(expresion)。
SELECT id, num, row_number() over(partition by num order by id) as SerialGroup FROM ContinueNumber
3. 经过上述操作,两个列(SerialNum,SerialGroup)对应相减,只要连续,相减得到的值是一样的,不连续的话,相减得到的值不同。
SELECT Id,Num, row_number() over(order by id) - row_number() over(partition by Num order by Id) as SerialNumberSubGroup FROM ContinueNumber
4. 通过步骤3的操作,通过num和SerialNumberSubGroup列进行分组,最后拿到Num,就是得到的数据,去重是因为有可能同一个数字在多处出现三次以上。
SELECT DISTINCT Num FROM ( SELECT Num,COUNT(1) as SerialCount FROM (SELECT Id,Num, row_number() over(order by id) - ROW_NUMBER() over(partition by Num order by Id) as SerialNumberSubGroup FROM ContinueNumber) as Sub GROUP BY Num,SerialNumberSubGroup HAVING COUNT(1) >= 3) as Result