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
筛选排名百分之N可以用 PERCENT_RANK()over这个窗口函数
1 回复 分享
发布于 2021-12-14 11:28
的确非常经典,思路学习了!赞!!
1 回复 分享
发布于 2021-06-21 22:31
点赞 回复 分享
发布于 2021-09-12 00:43

相关推荐

头顶尖尖的程序员:我也是面了三四次才放平心态的。准备好自我介绍,不一定要背熟,可以记事本写下来读。全程控制语速,所有问题都先思考几秒,不要急着答,不要打断面试官说话。
点赞 评论 收藏
分享
06-26 15:33
青岛工学院 Java
积极的秋田犬要冲国企:他现在邀请我明天面试
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-11 12:31
以前小时候我最痛恨出轨、偷情的人,无论男女,为什么会出轨?现在我成了自己最讨厌的人,没想到分享的东西在牛客会被这么多人看,大家的评价都很中肯,我也认同,想过一一回复,但我还是收声了,我想我应该说说这件事,这件事一直压在我心里,是个很大的心结,上面说了人为什么出轨,我大概能明白了。我们大一下半年开始恋爱,开始恋爱,我给出了我铭记3年的承诺,我对她好一辈子,我永远不会背叛,我责任心太重,我觉得跟了我,我就要照顾她一辈子,我们在一起3年我都没有碰过她,她说往东我就往东,她说什么我做什么,她要我干什么,我就干什么!在学校很美好,中途也出过一些小插曲,比如男闺蜜、男闺蜜2号等等等。但我都强迫她改掉了,我...
牛客刘北:两个缺爱的人是没有办法好好在一起的,但世界上哪有什么是非对错?你后悔你们在一起了,但是刚刚在一起的美好也是真的呀,因为其他人的出现,你开始想要了最开始的自己,你的确对不起自己,21岁的你望高物远,你完全可以不谈恋爱,去过你想要的生活,你向往自由,在一起之后,你要想的不是一个人,而是两个人,你不是变心了,就像你说的,你受够了,你不想包容了,冷静几天是你最优的选择,爱人先爱己。
社会教会你的第一课
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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