前言
就一直向前走吧,沿途的花终将绽放~
题目:找出连续活跃3天及以上的用户
sql
create table t_useractive(
uid string,
dt string
);
insert into t_useractive
values('A','2023-10-01'),('A','2023-10-02'),('A','2023-10-03'),('A','2023-10-04'),
('B','2023-10-01'),('B','2023-10-03'),('B','2023-10-04'),('B','2023-10-05'),
('C','2023-10-01'),('C','2023-10-03'),('C','2023-10-05'),('C','2023-10-06'),
('D','2023-10-02'),('D','2023-10-03'),('D','2023-10-05'),('D','2023-10-06');
hsql:
sql
select uid
from (
select uid
from
(select uid,dt,row_number() over (partition by uid order by dt) rn,
date_sub(dt, row_number() over (partition by uid order by dt)) c1
from t_useractive
) t1 group by uid,c1
having count(*) >= 3
)
t2 group by uid;
hsql分析:
子查询 t1:
- 从
t_useractive
表中选择uid
、dt
。- 使用
row_number() over (partition by uid order by dt)
为每个用户的活动记录分配一个行号(按照日期排序)。这个行号被命名为rn
。- 接下来,计算一个名为
c1
的字段,该字段是日期dt
减去行号rn
的结果。这样做的目的是为了标记连续的日期,因为对于连续的日期,date_sub(dt, rn)
的结果将是相同的。子查询 t1 的分组:
- 使用
group by uid, c1
对子查询t1
的结果进行分组。由于c1
字段对于连续的日期是相同的,因此这将把连续的日期记录分组在一起。having count(*) >= 3:
- 筛选出那些组中记录数大于或等于3的组,这意味着这些组代表了连续3天或更多的活动。
外部查询 t2:
- 由于内部查询已经筛选出了连续3天或更多的活动组,外部查询只需简单地按
uid
进行分组,并选择uid
字段。这一步是为了确保每个用户只被列出一次,即使他们在不同的时间段内有多个连续的3天或更多天的活动。最终,这个查询将返回所有在
t_useractive
表中至少有连续3天活动的用户的uid
。