题解 | #9行代码解决# #每个人最近的登录日期(四)#
牛客每个人最近的登录日期(四)
https://www.nowcoder.com/practice/e524dc7450234395aa21c75303a42b0a
提供一个用OVER()和PARTITION的解法,好像还没有人这么写,非常简单方便, 只要9行
思路:
- 做一个FROM 的subquery,目的是能够让所有第一次登陆的新用户的排名是1,后期用来筛选:用窗口函数,按照user_id分组,按照日期升序排序。
- 按照日期分组,并计算不同日期下排名为1的行数之和
SELECT t.date, SUM(IF(t.r = 1, 1, 0)) FROM(SELECT user_id, date, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY date) AS r FROM login ) AS t GROUP BY date
---------------------------------分割线-------------------------------------------------------------
下面还有一个更复杂的方法,只是在外部查询的部分做了改动。
其实下面的方法是一开始想到的,上面的方法算是做了优化
SELECT t1.date, COALESCE(t2.cnt, 0) AS cnt FROM (SELECT DISTINCT date FROM login) AS t1 LEFT JOIN ( SELECT date, COUNT(*) AS cnt FROM (SELECT user_id, date, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY date) AS r FROM login ) AS t WHERE t.r = 1 GROUP BY date ) AS t2 USING (date)
因为进行WHERE筛选过后,只留下了有新用户的日期。因此我们要再次与日期JOIN,并且将NULL值转化为0