sql常见笔试题目类型(3)最大连续天数

最大连续天数的问题也是非常常见的一个题型,比较常见的形式就是连续签到n次以上的人数,统计最大连续登录天数等等。
最大连续天数的有一个较为通用的解法,这个通用解法放在后面具体描述。

解题思路

首先思考一个简单的问题,怎么统计连续两天登录人数:连续两天登录就是一个人在登录后第二天继续登录了,只要找到登录日期的第二天有登录记录就行了。显然通过自连接,很容易就能够做到。
然后是连续三天登录人数,显然通过两次自连接,同样能够得到连续三天登录的人数。但是当连续n天登录人群的n足够大的时候,比如7天连续登录,30天连续登录,再用自连接来做就很难完成了。
从这个角度发散一下,连续n天登录就是为了找到连续的一段日期,如果对日期进行排序(假设日期没有重复),每一段连续的日期,减去它的排名,得到的日期是相同的。

日期排名差值
1-111-0
1-221-0
1-331-0
1-641-2
1-1051-5
1-1161-5
1-1271-5

在得到差值之后,很显然,统计相同值出现的次数就是连续登录的天数,同样,相同值出现的最大次数就是最大连续登录天数。

解题步骤

为了实现上述想法,需要一步一步构建需要的数据,第一步:对登录日期进行排序,这里就要用到窗口函数了,如果没有重复值直接用row_number()就行,如果有重复值就要用dense_rank()了。
第二步:计算日期与排名的差值,这里需要使用时间函数,一般来说date_sub()就可以了,如果日期格式较为复杂,在上一步可以对其用date_format()进行修改格式,也可以用其他形式的时间差函数。
第三步,对差值进行统计。这里直接用group by进行聚类就行了。

示例

这里拿牛客网上的一道题来做示例(SQL29 某宝店铺连续2天及以上购物的用户及其对应的天数
11月结束后,小牛同学需要对其在某宝的网店就11月份用户交易情况和产品情况进行分析以更好的经营小店。11月份销售数据表sales_tb如下(其中,sales_date表示销售日期,user_id指用户编号,item_id指货号,sales_num表示销售数量,sales_price表示结算金额):
在这里插入图片描述
请你统计连续2天及以上在该店铺购物的用户及其对应的次数(若有多个用户,按user_id升序排序),以上例子的输出结果如下:在这里插入图片描述

#第三步 进行统计
select b.user_id,count(diff_date) as days_count
from (
#第二步 计算差值
select a.user_id,a.sales_date,date_sub(a.sales_date,INTERVAL rn day ) diff_date
from (
#第一步 进行排序
select user_id,
sales_date,
row_number() over (partition by user_id order by sales_date) rn
from sales_tb) a
)b
group by b.user_id,diff_date
having days_count>=2
order by user_id

版权声明:本文为weixin_40265541原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。