需求: 连续登录4天及以上的用户
方法一:
排序窗口函数 row_number()
select *
,row_number() over (partition by user_id order by login_date) as ranking
from login_test
结果为:
可以看到连续登录的话,login_date-ranking的日期应该相等
select
*,
date_sub(login_date,interval ranking day) as day
from
(select
*,
row_number() over (partition by user_id order by login_date) as ranking
from login_test) t
然后只需根据user_id和day列进行分组,求count大于4的就可以。完整代码如下:
select
user_id,
login_date,
t.day,
count(1)
from
(select
user_id,
login_date,
date_sub(login_date,interval row_number() over (partition by user_id order by login_date) day) as day
from login_test
)t
group by user_id, day
having count(1)>=4
结果如下:
方法二:
将用户登录的时间向前偏移,如求连续四天登录的用户,只用把日期向前偏移3天,如果偏移之后的日期正好等于登录时间-3天,则表示该用户连续登录了四天。
偏移使用lead()函数
LEAD()是一个Window函数,它提供对当前行之后的指定物理偏移量的行的访问。
例如,通过使用LEAD()函数,可以从当前行访问下一行的数据或下一行之后的行,依此类推。
LEAD()函数对于将当前行的值与后续行的值进行比较非常有用。
以下是LEAD()
函数的语法:
LEAD(return_value ,offset [,default])
OVER (
[PARTITION BY partition_expression, ... ]
ORDER BY sort_expression [ASC | DESC], ...
)
在上面语法中,
-
return_value
- 基于指定偏移量的后续行的返回值。返回值必须求值为单个值,不能是另一个Window函数。 -
offset
是从当前行转发的行数,用于访问数据。offset
可以是表达式,子查询或列,其值为正整数。如果未明确指定,则offset
的默认值为1
。 - 如果
offset
超出分区范围,则该函数返回default
。 如果未指定,则默认为NULL
。 -
PARTITION BY
子句将结果集的行分配到应用了LEAD()
函数的分区。 - 如果未指定
PARTITION BY
子句,则该函数将整个结果集视为单个分区。 -
ORDER BY
子句指定应用LEAD()
函数的每个分区中行的逻辑顺序。
因此使用代码:
select *,
lead(login_date,3) over(partition by user_id order by login_date desc) as testday
from login_test
得出结果:
然后筛选出login_date-3等于testday的数据,最后使用group by进行去重就行
select
user_id
from
(select user_id,
login_date,
lead(login_date,3) over(partition by user_id order by login_date desc) as testday
from login_test
)t
where date_sub(login_date ,interval 3 day) = testday and testday is not null
group by user_id
原文地址:https://www.jb51.cc/wenti/3283510.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。