题解 | #牛客每个人最近的登录日期(五)#

牛客每个人最近的登录日期(五)

http://www.nowcoder.com/practice/ea0c56cd700344b590182aad03cc61b8

知识点

  1. 根据题目想要的表格的形状首先按照日期排列,知道每个日期有哪些新用户,然后第二天该用户登录信息没有也要出现null值因此该题使用左连接
  2. 第一步日期排列代码如下
 select date 
 from login
 group by date
  1. 该日期有哪些新用户代码如下,即使出现同一人当天多次登录的情况这样写也不会出现重复。日期没有新人后面就是null值
select user_id, min(date) as date
from login
group by user_id
  1. 然后再左连接login表,连接条件为用户id同时使用datediff(date1,date2) 返回起始时间 date1 和结束时间 date2 之间的天数为1。若没有符合条件的连接的表date就是null值。
  2. 由于出现null值可以直接使用ifnull。如果不是 NULL,则返回第一个参数。 否则,IFNULL 函数返回第二个参数。该题出现null值就是0
  3. 计算留存率,有可能出现第二天登录多次的情况所以计数时使用distinct。

代码

select d1.date,
ifnull (round( 
             count(distinct l.user_id)/(count(distinct d2.user_id)), 3) ,0) as p
from(
    select date 
    from login
    group by date) as d1
left join
    (
    select user_id, min(date) as date
    from login
    group by user_id) as d2
on d1.date = d2.date
left join login as l
on d2.user_id = l.user_id
and datediff(l.date, d2.date) = 1
group by d1.date

补充

  1. on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
  2. where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉,on后的条件用来生成左右表关联的临时表,where后的条件对临时表中的记录进行过滤。
全部评论

相关推荐

等闲_:小红书基本不区分日常和暑期,你是应届实习时间够了就有转正机会,只要部门有hc
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务