4-3 SQL经典真题解析

在笔试面试中,会有一些反复出现的,要求我们掌握的题目,本章中会介绍六类经典的问题及解法。在第一次看见问题时,可能并不能马上想到思路,但多加练习后还是能够快速解决的。

1、连续问题

假如有一张表table1记录了每个用户登录APP的时间

 

(1)取出连续数据。

现在想取出连续3天以上登录了该APP的用户名单

针对这种连续的问题最常规的思路是借助row_number()over()的开窗函数我们先看一下使用开窗函数的效果

select *, row_number()over(partition by id order by date)as rk
from table1


在这个结果中,用日期数据减去排名数据,如果日期是连续的,那么相减后的结果一致,如对于用户1来说,20200101-1=20200102-2=20200103-3=20200104-4=20200100。根据这一原理,若对于某个id来说,相减后的结果中有3个及以上相同,则可认为这一id连续登陆了3天及以上。具体的代码如下:

select b.id, b.results, count(1)as num
from
    (select a.*,(a.date - a.rk)as results
    from
        (select *,row_number()over(partition by id order by date)as rk
        fromm table1
        )a
     )b
group by b.id, b.results
having num>=3 


(2)取出不连续数据

在上面一题中,我们通过用日期减去排序结果的方式得到了连续数据,如果我想取出连续3天及以上未登录的用户,应该怎么做呢?

我们试着用一个新窗口函数,lag()over()lag窗口函数可以将指定列记录向下平移例如:

select *, lag(date)over(partition by id order by date)as date2
from table1 


通过观察date和date2列,我们发现两者之差和用户连续未登录天数有关。例如,对于用户2来说,date=20200106时,date2=20200102,就是说用户2在1月2日登陆后,3、4、5三天都没有登陆,第二次登陆已经是1月6日了。因此,我们可以写成:

select b.*
from
    (select a.*,(a.date-a.date2-1)as num
     from
         (select *,lag(date)over(partition by id order by date)as date2
         from table1
         )a
     )b
where b.num>=3 

2、新增与留存问题

现有table1,记录了用户id以及登录日期表结构如下

 

(1)新增用户数统计

在进行用户指标监控时,拉新人数往往是很重要的指标之一。我们来看一下如何获取每天新增用户的数量。以table1为例,最简单的思路就是先用row_number开窗函数获取用户的登陆时间的排序,取出排序为1的记录后,在时间维度对用户id进行去重聚合即可:

select a.date, count(distinct id)as num
from
   (select *, row_number()over(partition by id order by date)as rk)
    from table1
    )a
where a.rk=1
group by a.date 

(2)用户留存统计

若想统计3日留存人数(即在第一次登陆后,3天内有过第二次登陆行为的用户数量)可以考虑将table2表做自连接,在on的条件中通过限定date的差值控制在1-3的范围内进行筛选。

select a.*, b.date
from table1 a
left join table1 b on a.id=b.id and b.date-a.date<=3 and b.date-a.date>=1  

我们会发现若用户在3天内有回访行为,b表的date列能够和a表的date列匹配成功不会出现null。根据这一特征,我们可以筛选目标用户,结合在1中计算新用户的逻辑,可以写出:

select aa.date, count(a

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

<p> 为什么要学习本专刊 (1)数据分析面试日益激烈,招聘门槛提高,对业务、技术的综合考察难度上升; (2)网上对数据分析面试题型的整理与解析质量参差不齐,缺少框架清晰、内容全面的学习资料; (3)直击数据分析面试热点问题; </p>

全部评论
连续登录问题中: 当日期不重复时,用ROW_NUMBER()、RANK()、DENSE_RANK()皆可; 当日期记录会重复时(一天内登录多次),需加一个对日期的去重处理,否则三种排序函数计算的结果都有误。
2 回复 分享
发布于 2022-01-04 15:48
的确非常经典,思路学习了!赞!!
1 回复 分享
发布于 2021-06-21 22:31
筛选排名百分之N可以用 PERCENT_RANK()over这个窗口函数
1 回复 分享
发布于 2021-12-14 11:28
点赞 回复 分享
发布于 2021-09-12 00:43

相关推荐

我见java多妩媚:大外包
点赞 评论 收藏
分享
评论
点赞
1
分享
牛客网
牛客企业服务