现有一表user_login_table代表表名
user_name代表用户ID
date代表用户登录时间
其结构数据如下:
例题1:求连续7天登录过的用户ID
思路一:首先对用户登录的日期去重-通过row_number窗口函数对每个用户登录时间升序排列得到新列rn-通过date1列减去rn列得到一个新列date2-通过判断date_2的计数>=7即可得到连续登录7天的用户。
具体代码如下:
select user_name,
date2
from (select *,
date1-rn date2
from(select * ,
row_number () over (partition by user_name order by date1 ) as rn
from (select distinct date(date) as date1,
user_name
from user_login_table)b)c)d
group by user_name,date2
having count(*)>=7;
补充知识点:
排名窗口函数
离散的组内排序(113)-rank() over (partition by ... order by ... )
连续的组内排序(112)-dense_rank() over (partition by ... order by ... )
当前行在组内的序号(123)-row_number() over (partition by ... order by ... )
子查询
where子查询-指把内层查询结果作为外层查询的比较条件
from子查询-把内层sql的查询结果,当成临时表供外层sql再次查询,临时表
需要声明表名
exist子查询-指把外层sql的结果,拿到内层sql比较,为真则输出结果
思路二:通过lead函数将date列日期向后偏移7次,通过偏移7次后的日期与date列日期向后7天的日期比较,如果两者相等,则说明用户连续登录了7天。
具体代码如下:
select user_name
from (select user_name,
CAST(date as date) as date_1,
LEAD(CAST(date AS date),7) over (partition by user_name order by date) as date_2
from user_login_table) a
where DATE_ADD(a.date_1,INTERVAL 6 day)=a.date_2;
补充知识点:
将值转换为指定类型-CAST(字段名 as 转换类型)
转换类型可为以下类型:
CHAR[(N)] 字符型
DATE 日期型
DATETIME 日期和时间型
DECIMAL float型
SIGNED int
TIME 时间型
向后偏移-LEAD(字段名,偏移量,默认null) over(partition by ...order by …) 向前偏移-LAG(字段名,偏移量,默认null) over(partition by ...order by …)
向日期添加指定时间间隔-DATE_ADD(字段名,INTERVAL 时间间隔 单位)
常用单位可为以下类型:
向日期减去指定时间间隔-DATE_SUB(字段名,INTERVAL 时间间隔 单位)
单位如上图所示。