题目:
下面表格是用户访问表users,记录了用户id(usr_id)和访问日期(log_date),求出连续3天以上访问的用户id。
思路:
-
按照 用户 id 开窗,给访问日期排名(重复的不多占排名,所以用
DENSE_RANK()
) -
用访问日期减去排名,得到一个时间tmp ,如果用户是连续访问的,那么这个时间差
tmp
就是一样的! -
一个用户的这个时间如果出现3次及以上,说明这个用户连续访问了3天。
(1)先按照用户id(usr_id)对访问日期(log_date)进行排名,这里用DENSE_RANK()
而不是 RANK()
SELECT usr_id,log_date,
DENSE_RANK() OVER (PARTITION BY usr_id order_by log_date) AS rank
FROM users;
(2) 得到排名后,用log_date 减去 排名序号!得到差值 tmp
;
SELECT
usr_id,
DATE_SUB(log_date,INTERVAL rank DAY) AS tmp / 用log_date 减去 排名序号!
FROM (
SELECT
usr_id,
log_date,
DENSE_RANK() OVER (PARTITION BY usr_id ORDER BY log_date) AS rank
FROM users
) AS A ;
(3)同一个用户有3个及以上的 时间差值tmp 相同,说明用户连续访问了3天,所以我们对用户和tmp进行分组,并统计判断tmp大于等于3的;
注意:
- 在MySQL中,group by可以使用select的别名!Hive 不行!
- 在MySQL 和 Hive中,Having都能使用 select 中的别名 !)
SELECT
usr_id,
DATE_SUB(log_date,INTERVAL rank DAY) AS tmp
FROM (
SELECT
usr_id,
log_date,
DENSE_RANK() OVER (PARTITION BY usr_id ORDER BY log_date) AS rank
FROM users
) AS A
GROUP BY usr_id, tmp / 联合分组
HAVING COUNT(flg_date) >=3 ;
(4)这样就已经得出最终结果了,因为题目只想知道usr_id,我们最后再将usr_id展示出来就可以了。
最终具体代码如下:
SELECT DISTINCT usr_id
FROM(
SELECT
usr_id,
DATE_SUB(log_date,INTERVAL rank DAY) AS tmp
FROM (
SELECT
usr_id,
log_date,
DENSE_RANK() OVER (PARTITION BY usr_id ORDER BY log_date) AS rank
FROM users
) AS A
GROUP BY usr_id,tmp
HAVING COUNT(tmp) >=3
) AS B
参考:https://blog.csdn.net/m0_66557301/article/details/126055254
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/89168.html