问题举例:
- 求每个用户相邻两次浏览时间之差小于3min的次数
- 求用户相邻两次提交时间小于1h的次数
- 求用户购买同一商品的间隔时长
实例:
<题目>
给定一张用户浏览时间表user_pv_time,表中包含两个字段,分别是用户id:【user_id】和用户访问时间【user_time】
<问题>
求每个用户相邻两次浏览时间之差小于3min的次数
<解题思路>
思路一:
既然是求每个用户XX,最后一定要按照用户id进行分组;又要求是相邻两次浏览时间,所以要对每个用户的浏览时间排序号,利用序号的差值为1即可判断是相邻;
SELECT a.user_id, COUNT(*) AS pv_count
FROM (SELECT user_id, user_time,
ROW_NUMBER() OVER (partition by user_id
order by user_time) AS rn
FROM user_pv_time) AS a
LEFT JOIN (SELECT user_id, user_time,
ROW_NUMBER() OVER (partition by user_id
order by user_time) AS rn
FROM user_pv_time) AS b
ON a.user_id = b.user_id
WHERE CAST(b.rn AS signed) - CAST(a.rn AS signed) = 1
AND TIMESTAMPDIFF(MINUTE, a.user_time, b.user_time) < 3
GROUP BY user_id
这里用到了CAST()函数和TIMESTAMPDIFF()函数,解释如下:
- CAST函数主要是转换字段类型,语法规则是:Cast(字段名 as 转换的类型 ),其中类型可以为:CHAR[(N)]:字符型,DATE:日期型,SIGNED:int型等。
- TIMESTAMPDIFF()语法规则是(unit,begin,end),返回begin-end的结果,其中begin和end是DATE或DATETIME表达式,unit参数是确定(end-begin)的结果的单位,表示为整数,取值可以是秒second,分钟minute,小时hour和天day等。
思路二:
上面涉及到了两表连接,这里有一个可以避免多表连接的办法,就是使用窗口函数lead(),具体使用方法可以参考我的这篇文章:
狗哥:数据分析|SQL窗口函数zhuanlan.zhihu.com# 解法二 窗口函数
SELECT t.user_id, COUNT(*) AS pv_count
FROM (SELECT user_id, user_time,
LEAD(user_time, 1) OVER (partition by user_id
order by user_time) AS next_time
FROM user_pv_time) AS t
WHERE TIMESTAMPDIFF(MINUTE, user_time, next_time) < 3
GROUP BY user_id