【场景】:同时在线问题、连续时间
【分类】:聚合窗口函数、tag标记、合并行
分析思路
难点:
1.打车结束3种情况下的判断条件
2.考虑到可能有多个用户同时签入或者签出 使用union all 而不是 union
(1)统计在2021年10月期间,开始打车记录
开始打车记录 event_time
-
[条件]:date_format(event_time,'%Y%m') = '202110'
-
[使用]:开始打车 人数增加1 用tag = 1标记
(2)计算2021年10月商城里所有新用户的首单平均交易金额(客单价)和平均获客成本(保留一位小数)
结束打车对应3种情况
1.取消打车: order_id is null end_time 2.取消订单: start_time is null finish_time 3.上车前:start_time is not null start_time
-
[条件]:date_format(event_time,'%Y%m') = '202110'
-
[使用]:结束打车 人数减少1 用tag = -1标记;case when
(3)合并开始打车和取消打车的记录,得到整条时间线上人数增减的记录
使用union all 是因为可能有多个用户同时签入或者签出
- [使用]:union all
(4)统计单日同时等车人数
等车人数记作先增加后减少,所以要对 tag 降序
-
[条件]:date_format(event_time,'%Y%m') = '202110'
-
[使用]:sum(tag) over(partition by city order by time,tag desc)
(5)统计各个城市单日最大等车人数。结果按各城市最大等车人数升序排序,相同时按城市升序排序
按照 city 分组
- [使用]:group by city;order by max_wait_uv,city
扩展
前往查看: MySQL 在线人数 场景分析
求解代码
方法一:
with子句
with
main as(
#统计在2021年10月期间,开始打车记录event_time
select
city,
event_time as time,
1 as tag
from tb_get_car_record
where date_format(event_time,'%Y%m') = '202110'
)
,attr as(
#统计在2021年10月期间,打车结束记录
select
city,
(case
when order_id is null then end_time
when start_time is null then finish_time
when start_time is not null then start_time
end) as time,
-1 as tag
from tb_get_car_record
left join tb_get_car_order using(order_id)
where date_format(event_time,'%Y%m') = '202110'
)
,temp as(
#合并开始打车和取消打车的记录,得到整条时间线上人数增减的事件流
#使用union all 是因为可能有多个用户同时签入或者签出
(select *
from main)
union all
(select *
from attr)
order by city,time
)
,temp1 as(
#统计单日同时等车人数,等车人数记作先增加后减少,所以要对 tag 降序
select
city,
sum(tag) over(partition by city order by time,tag desc) as wait_uv
from temp
)
#统计各个城市单日最大等车人数。结果按各城市最大等车人数升序排序,相同时按城市升序排序
select
city,
max(wait_uv) as max_wait_uv
from temp1
group by city
order by max_wait_uv,city
方法二
from嵌套子查询
#统计各个城市单日最大等车人数。结果按各城市最大等车人数升序排序,相同时按城市升序排序
select
city,
max(wait_uv) as max_wait_uv
from(
#统计单日同时等车人数,等车人数记作先增加后减少,所以要对 tag 降序
select
city,
sum(tag) over(partition by city order by time,tag desc) as wait_uv
from(
#合并开始打车和取消打车的记录,得到整条时间线上人数增减的事件流
#使用union all 是因为可能有多个用户同时签入或者签出
(select *
from(
#统计在2021年10月期间,开始打车记录event_time
select
city,
event_time as time,
1 as tag
from tb_get_car_record
where date_format(event_time,'%Y%m') = '202110'
) main)
union all
(select *
from(
#统计在2021年10月期间,打车结束记录
select
city,
(case
when order_id is null then end_time
when start_time is null then finish_time
when start_time is not null then start_time
end) as time,
-1 as tag
from tb_get_car_record
left join tb_get_car_order using(order_id)
where date_format(event_time,'%Y%m') = '202110'
) attr)
order by city,time
) temp
) temp1
group by city
order by max_wait_uv,city