SQL数分题解1-33
SQL数分题解
1. 抖音每个直播间最大同时在线人数
明确题意:
统计每个直播间最大的同时在线人数是多少,并按在线人数降序排列
问题拆解:
- 整体思路:将进入时间和退出时间放在一列,并分别标记1和-1(表示在线人数加1和减1)后;再用窗口函数统计每个房间内截止当前时间的在线人数(求和标记列);最后按房间分组取最大即为每个直播间最大的同时在线人数。
- 将进入时间和退出时间放在一列,并分别标记1和-1。知识点:用union all将两次查询结果混合在一起。
- 统计每个房间内截止当前时间的在线人数。知识点:
sum(uv) over(partition by room_id order by at_time)
- 按房间分组取最大。知识点:group by;max()
代码实现:
select room_id, max(current_max) max_num
from (
select room_id, sum(uv) over(partition by room_id order by at_time) as current_max
from (
select room_id, in_time as at_time, 1 as uv
from user_view_tb
union all
select room_id, out_time as at_time, -1 as uv
from user_view_tb
order by room_id, at_time
) as t_at_time_uv
) as t_room_cur_max
group by room_id
2. B站大会员最多同时有多少
明确题意:
统计B站大会员最多同时有多少
问题拆解:
- 整体思路:将生效开始日期和结束日期放在一列,并分别标记1和-1(表示会员人数加1和减1)后;再用窗口函数统计截止当前日期的会员人数(求和标记列);最后取当前会员人数最大值。
- 将生效开始日期和结束日期放在一列,并分别标记1和-1。知识点:用union all将两次查询结果混合在一起。
- 统计截止当前日期的会员人数。知识点:
sum(uv) over(order by dt)
- 取当前会员人数最大值。知识点:max()
代码实现:
select max(current_max) as max_num
from (
select sum(uv) over(order by dt) as current_max
from (
select begin_date as dt, 1 as uv
from detail_list_tb
union all
select end_date as dt, -1 as uv
from detail_list_tb
) as t_dt_uv
) as t_cur_max
3. B站9月上中下旬的用户充值数量
明确题意:
统计9月上中下旬的用户充值数量
问题拆解:
- 筛选9月重置的用户(题目不严谨,应为2021年9月)。知识点:where;筛选9月用between and和DATE_FORMAT()函数都能实现,但是从效率角度来说,如果数据量很大时between and能使用索引(如果有),而DATE_FORMAT不能,因此建议优先使用between and。
- 判断日期是几号,划分到不同的旬,2个及以上的条件,建议使用case when;知识点: case when ... then ... else ... end。
- 统计每旬的数量。知识点:group by;count()
代码实现:
select seg_date, count(1) as cnt
from (
select
case
when DAY(begin_date) <= 10 then "上旬"
when DAY(begin_date) <= 20 then "中旬"
else "下旬"
end as seg_date
from detail_list_tb
where begin_date between "2021-09-01" and "2021-09-30"
) as t_seg
group by seg_date
4. B站会员2021年9月收入
明确题意:
计算2021年9月B站会员的收入(结果保留2位小数)
问题拆解:
- 筛选会员生效日期到结束日期时间窗和2021年9月有交集的记录。知识点:where
- 计算每个会员9月里是会员的起始日期和终止日期,以及会员的每天收入摊销。
- 计算每个会员9月里的总摊销。知识点:
- 计算2021年9月所有会员的总摊销收入。知识点:sum()
代码实现:
select round(sum((DATEDIFF(end_dt, start_dt) + 1) * day_pay), 2) as revenue
from (
select user_id,
IF(begin_date<'2021-09-01', date('2021-09-01'), begin_date) as start_dt,
IF(end_date>'2021-09-30', date('2021-09-30'), end_date) as end_dt,
pay_amount / days as day_pay
from detail_list_tb
where begin_date <= "2021-09-30" and end_date >= "2021-09-01"
) as t_start_end
5. B站9月新会员人数
明确题意:
统计9月份新会员人数
问题拆解:
- 统计每个会员用户作为新会员的日期。知识点:按用户分组group by;取最小日期min()
- 统计9月的新会员数量。知识点:筛选9月的新会员where between and;计数count() 上一步已经按用户分组了,因此这里不需要再加distinct
代码实现:
select count(user_id)
from (
select user_id, min(begin_date) as first_begin_date
from detail_list_tb
group by user_id
) as t_first_dt
where first_begin_date between "2021-09-01" and "2021-09-30"
滴滴
6. 乘客数大于1的司机信息
明确题意:
统计每位司机所载的乘客数大于1的司机id,乘客数以及所在的城市名称。
问题拆解:
- 统计每个司机的乘客数。知识点:count() group by
- 选出乘客数大于1的司机ID和乘客数,知识点:having
- 关联司机数据表,得到司机的城市ID。知识点:join
- 关联城市表,得到司机所在城市名称。知识点:join
- 按driver_id升序。知识点:order by xxx [asc]
代码实现:
select order_info_tb.driver_id, count(passenger_id) as passenger_num, city_name
from order_info_tb
left join driver_tb using(driver_id)
left join city_tb using(city_id)
group by driver_id
having passenger_num>1
order by driver_id
7. 订单量大于1的司机信息
明确题意:
各司机订单量大于1的城市名称、司机id、订单量
问题拆解:
- 统计司机的订单量,知识点:按司机ID分组:group by,对订单ID计数:count()
- 对分组结果进行筛选订单量大于1的结果,知识点:having
- 关联司机的城市ID。知识点:join
- 关联城市ID的城市名称。知识点:join
- 按driver_id升序排序。知识点:order by xxx [asc]
代码实现:
select city_name, order_info_tb.driver_id, count(order_id) as order_num
from order_info_tb
left join driver_tb using(driver_id)
left join city_tb using(city_id)
group by driver_id
having order_num>1
order by driver_id
8. 各司机总在线时长大于2小时的信息
明确题意:
统计各司机总在线时长大于2小时的城市名称,司机id和总在线时长
问题拆解:
- 求每个司机的总在线时长,知识点:按司机ID分组:group by;求和:sum
- 筛选总在线时长大于2小时的司机ID,知识点:分组后过滤having
- 关联司机ID的城市ID,知识点:join
- 关联城市ID的城市名称,知识点:join
代码实现:
select city_name, online_time_tb.driver_id, round(sum(online_len), 1) as online_sum
from online_time_tb
left join driver_tb using(driver_id)
left join city_tb using(city_id)
group by driver_id
having online_sum>2
9. 司机数大于15的城市
明确题意:
统计司机数大于15的城市
问题拆解:
- 关联每个司机的城市名称。知识点:join
- 统计每个城市的司机数。知识点:按城市分组group by;计数:count
- 筛选司机数大于15的城市。知识点:having
- 按driver_num升序排序。知识点:order by xxx [asc]
代码实现:
select city_name, count(driver_id) as driver_num
from driver_tb
left join city_tb using(city_id)
group by city_name
having driver_num>15
order by driver_num
10. 2021年8月和9月的北京新司机在线时长
明确题意:
统计2021年8月和9月,每个月的北京市新司机(首单日期在当月为新司机)的在线时长数据
问题拆解:
- 筛选8月和9月的新司机ID,知识点:where
- 关联各司机ID的在线时长,知识点:join
- 关联各司机ID的城市,知识点:join
- 求每个月北京的新司机当月在线时长。知识点:按月份分组group by;对时长求和sum
代码实现:
select DATE_FORMAT(finish_dt, "%Y-%m") as month, round(sum(online_len), 1) as online_line
from driver_tb
join online_time_tb using(driver_id)
join city_tb using(city_id)
where city_name="北京" and finish_dt between "2021-08-01" and "2021-09-30"
and DATE_FORMAT(finish_dt, "%Y%m")=DATE_FORMAT(online_time_tb.dt, "%Y%m")
group by month
11. 8月和9月北京市的新司机数
明确题意:
统计2021年8月和9月,每个月的北京市新司机(首单日期在当月为新司机)的司机数
问题拆解:
- 关联司机的城市,知识点:join
- 筛选8月和9月的新司机,知识点:where
- 筛选城市在北京的司机。知识点:where
- 统计8月9月新司机数。知识点:按月份分组group by;统计司机数count
代码实现:
select DATE_FORMAT(finish_dt, "%Y-%m") as month, count(driver_id) as driver_cnt
from driver_tb
join city_tb using(city_id)
where city_name="北京" and finish_dt between "2021-08-01" and "2021-09-30"
and DATE_FORMAT(finish_dt, "%Y%m")=DATE_FORMAT(dt, "%Y%m")
group by month
12. 9月各城市每天快车总流水数据
明确题意:
统计2021年9月各城市的快车流水数据
问题拆解:
- 关联订单表和司机表,得到每个订单中司机的城市ID。知识点:join
- 关联城市表,得到每个司机的城市名。知识点:join
- 筛选订单时间为9月且产品线类型为快车的记录。知识点:where
- 统计各城市的快车流水。知识点:按城市分组group by;统计流水count
- 按city_id、dt排序。知识点:order by
代码实现:
select city_name, order_info_tb.dt as dt, sum(account)
from order_info_tb
join driver_tb using(driver_id)
join city_tb using(city_id)
where product_line_id=2 and order_info_tb.dt >= "2021-09-01" and order_info_tb.dt <= "2021-09-30"
group by city_name, dt
order by driver_tb.city_id, dt
13. 2021年9月各城市每天的快车订单量
明确题意:
统计2021年9月各城市每天的快车订单量
问题拆解:
- 关联订单表和司机数据表,得到每个订单中司机的城市ID。知识点:join
- 关联城市表,得到每个司机的城市名
- 筛选9月份的快车订单。知识点:where
- 统计每个城市每天的订单量。知识点:按城市和日期分组group by;对订单数计数count
- 由于司机数据表有重复driver_id,因此需要对统计订单数量时需要去重
- 按city_id、dt排序
代码实现:
select city_name, order_info_tb.dt as dt, count(distinct order_id) as flash_count
from order_info_tb
join driver_tb using(driver_id)
join city_tb using(city_id)
where product_line_id=2 and order_info_tb.dt >= "2021-09-01" and order_info_tb.dt <= "2021-09-30"
group by city_name, dt
order by driver_tb.city_id, dt
14. 9月各城市每天的司机数
明确题意:
统计9月份各城市每天的司机数
问题拆解:
- 关联司机的城市名。知识点:join
- 筛选9月活跃的司机记录。知识点:where
- 统计各城市每天的司机数。知识点:按城市和日期分组group by;统计司机数量count
- 根据示例数据,按城市名倒序
代码实现:
select city_name, dt, count(distinct driver_id) as driver_num
from driver_tb
join city_tb using(city_id)
where dt >= "2021-09-01" and dt <= "2021-09-30"
group by city_name, dt
order by driver_tb.city_id
哔哩哔哩
15. 哔哩哔哩某日新增会员数
明确题意:
统计2021年9月4日新增的会员数量
问题拆解:
- 计算每个会员作为新增会员的日期。知识点:先筛选会员where;按用户id分组group by;取最小值min()
- 筛选20210904新增的会员。知识点:子查询、where
代码实现:
select view_date, count(user_id) as new_num
from (
select user_id, min(view_date) as view_date
from user_view_tb
where if_vip=1
group by user_id
) as t_min_date
where view_date='2021-09-04'
抖音
16. 抖音各类型的直播间平均观看时长
明确题意:
统计娱乐类、搞笑类中各个直播间的平均在线时长(退出时间-进入时间),单位为分钟(保留小数点后两位),并按在线时长降序排序
问题拆解:
- 关联每个观看记录的直播间类型。知识点:join
- 筛选出直播间类型为娱乐类、搞笑类的观看记录。知识点:where
- 计算每个观看记录的观看时长。知识点:TIMESTAMPDIFF
- 统计各个类别的直播间平均在线时长。知识点:按类别分组group by;计算平均时长avg。
- 保留两位小数。知识点:round()
- 按在线时长降序排序
代码实现:
select room_type, room_name,
round(avg(TIMESTAMPDIFF(MINUTE, in_time, out_time)), 2) as duration_min
from user_view_tb
join room_info_tb using(room_id)
where room_type in ("娱乐", "搞笑")
group by room_type, room_name
order by duration_min desc
17. 抖音20:00-23:00各类型的直播间观看总时长
明确题意:
统计20:00-23:00点之间各类型的直播间观看总时长(单位分钟,保留小数点后两位),并按观看总时长降序降序。
问题拆解:
- 关联观看记录的直播类型。知识点:join
- 筛选观看时间在20:00-23:00点之间的记录。知识点:where
- 统计各类型观看总时长。知识点:按类型分组group by;计算每次观看时长TIMESTAMPDIFF;统计总时长sum()
- 总时长保留2位小数。知识点:round(..., 2)
- 按观看总时长降序降序。知识点 order by ... desc
代码实现:
select room_type,
round(sum(TIMESTAMPDIFF(
MINUTE,
greatest(in_time, str_to_date("20:00:00", '%H:%i:%s')),
least(out_time, str_to_date("23:00:00", '%H:%i:%s'))))
, 2) as sum_view_minute
from user_view_tb
join room_info_tb using(room_id)
where in_time < "23:00:00" and out_time > "20:00:00"
group by room_type
order by sum_view_minute desc
18. 抖音直播间晚上11-12点之间各直播间的在线人数
明确题意:
统计抖音直播间11-12点之间各直播间的在线人数,并按人数降序排序
问题拆解:
- 关联观看直播记录的直播房间名。知识点:join
- 筛选出11-12点还在线的观看记录。知识点:where
- 统计在线人数。知识点:按直播间分组group by;对人数计数count(distinct user_id)
- 按人数降序排序。知识点:order by ... desc
代码实现:
select room_id, room_name, count(distinct user_id) as user_count
from user_view_tb
join room_info_tb using(room_id)
where in_time <= "23:59:59" and out_time > "23:00:00"
group by room_type, room_name
order by user_count desc
19. 抖音直播间各个时间段的在线人数
明确题意:
统计7:00-9:00(早通勤)、18:00-20:00(晚通勤)、12:00-14:00(午休)、22:00-24:00(临睡)各个时间段的在线人数。
问题拆解:
- 标记每条记录是否在4个时段内在线。知识点:
if(in_time <= "23:59:59" and out_time > "22:00:00", user_id, null)
- 统计每个时段在线用户数。count(distinct)
代码实现:
select count(distinct if(in_time < "09:00:00" and out_time > "07:00:00", user_id, null)) as `早通勤`,
count(distinct if(in_time < "20:00:00" and out_time > "18:00:00", user_id, null)) as `晚通勤`,
count(distinct if(in_time < "14:00:00" and out_time > "12:00:00", user_id, null)) as `午休`,
count(distinct if(in_time <= "23:59:59" and out_time > "22:00:00", user_id, null)) as `临睡`
from user_view_tb
微博
20. 微博历史签到中最大连续签到天数
明确题意:
计算每个用户历史签到中最大连续签到天数
问题拆解:
- 对每个用户筛选签到了的记录按顺序编号。知识点:筛选签到记录where;按顺序编号
row_number() over(partition by user_id order by sign_date)
; - 计算每个用户每次连续的签到天数。知识点:按用户ID、签到日期减去序号(即本次连续签到起始日期)分组group by;统计连续签到天数count();
- 统计每个用户最大连续签到天数
- 按user_id升序排序
代码实现:
select user_id, max(continuous_days) as max_continuous_days
from (
select user_id, count(*) as continuous_days
from (
select user_id, sign_date,
row_number() over(partition by user_id order by sign_date) as rn
from user_sign_tb
where if_sign=1
) as t_sign_date_rn
group by user_id, DATE_ADD(sign_date, INTERVAL -rn day)
) as t_continuous_days
group by user_id
order by user_id
21. 微博截止到当前每个用户已经连续签到的天数
明确题意:
计算截止到6月13号每个用户已经连续签到的天数
问题拆解:
- 筛选2021-6-13及之前签到了的记录。知识点:where
- 对每个用户按签到日期倒序编号。知识点
row_number() over(partition by user_id order by sign_date desc)
; - 筛选签到日期加上序号天后为2021-06-14的记录(即连续签到至2021-06-13的记录)。知识点:where、DATE_ADD
- 统计每个用户的连续签到天数。知识点:按用户ID分组group by;对签到天数计数count
- 按user_id升序排序
代码实现:
select user_id, count(*) as continuous_days
from (
select user_id, sign_date,
row_number() over(partition by user_id order by sign_date desc) as rn
from user_sign_tb
where if_sign=1 and sign_date<="2021-6-13"
)as t_sign_date_rn
where DATE_ADD(sign_date, INTERVAL rn day)="2021-6-14"
group by user_id
order by user_id
哔哩哔哩
22. 某天最受欢迎的番剧
明确题意:
统计'2020-1-1'日最受欢迎的番剧及对应的用户数
问题拆解:
- 关联番剧的名字。知识点:join
- 筛选观看番剧的日期。知识点:where
- 统计每个番剧被观看的人数。知识点:按番剧名分组group by;统计次数count(distinct )
- 筛选最受欢迎(观看人数最大)的番剧。按观看人数倒序排序order by ... desc;取第一个limit 1
代码实现:
select count(distinct user_id) as num, vidio_name
from user_view_tb
join vidio_info_tb using (vidio_id)
where view_date="2021-01-01"
group by vidio_name
order by num desc, video_id
limit 1
23. 哪一类视频观看人数最多
明确题意:
统计哪一类视频的观看人数最多
问题拆解:
- 关联番剧的类别。知识点:join
- 统计每个番剧类别被观看的人数。知识点:按番剧名分组group by;统计人数count(distinct)
- 筛选观看人数最多的番剧类别。按观看人数倒序排序order by ... desc;取第一个limit 1
代码实现:
select vidio_type, count(distinct user_id) as num
from user_view_tb
join vidio_info_tb using (vidio_id)
group by vidio_name
order by num desc
limit 1
24. 鬼畜区的用户里有多少用户看过汽车区
明确题意:
计算鬼畜区的用户里,有多少用户看过汽车区。 对于本题,等价于计算既看过鬼畜区又看过汽车区的用户数。
问题拆解:
有两种解法。解法1:用鬼畜区用户join汽车区用户。
- 关联视频类型,只保留鬼畜和汽车类的视频,并取唯一结果。知识点:关联表join;筛选类型where in;取唯一distinct;
- 筛选出鬼畜区的用户。知识点:where
- 筛选出汽车区的用户。知识点:where
- 关联两批用户。知识点:join
- 对用户计数。知识点:count
解法2:只保留每个用户观看的鬼畜区或汽车区的用户ID、区域类型;筛选观看过的这两个类型的类型个数为2的用户数。
- 关联视频的类型。知识点:join
- 筛选视频类型为鬼畜或汽车的记录。知识点:where
- 统计观看过这些区的区域个数为2的用户。知识点:按用户分组gourp by;对观看区域个数计数count(distinct vidio_type)=2
- 对满足上述条件的用户计数。知识点:count
代码实现:
with t_user_vidio_type as (
select distinct user_id, vidio_type
from user_view_tb
join vidio_info_tb using (vidio_id)
where vidio_type in ("鬼畜", "汽车")
)
select count(user_id)
from (
select user_id from t_user_vidio_type
where vidio_type="鬼畜"
) as t_evil
join (
select user_id from t_user_vidio_type
where vidio_type="汽车"
) as t_car
using(user_id)
select count(distinct user_id) as num
from (
select user_id
from user_view_tb
join vidio_info_tb using (vidio_id)
where vidio_type in ("鬼畜", "汽车")
group by user_id
having count(distinct vidio_type)=2
)
25. 618不同价格区间的购买人数
明确题意:
统计0-50,50-100,100-200三个价格区间的购买人数
问题拆解:
- 关联行为表于产品表的价格。知识点:join
- 筛选购买行为的记录。知识点:where
- 把价格变成区间。知识点:case when then
- 统计每个区间的购买人数。按区间分组group by;统计人数count(distinct cust_uid)
- 按price_cut_num降序排序
代码实现:
select
case
when price<50 then "0-50"
when price<100 then "50-100"
when price<=200 then "100-200"
end as price_cut,
count(distinct cust_uid) as price_cut_num
from tb_clk_rcd
join tb_prd_map using(prd_id)
where if_buy=1
group by price_cut
order by price_cut_num desc
26. 618活动购买每个商品的用户的平均年龄
明确题意:
计算购买每个商品的用户的平均年龄(结果保留两位小数)
问题拆解:
- 关联用户信息表中的年龄。知识点:join
- 筛选购买行为记录。知识点:where
- 统计购买每个商品的平均年龄。知识点:按商品分组group by;计算年龄平均值avg
- 结果保留两位小数。知识点:round
- 按商品ID排序
代码实现:
select prd_id, round(avg(age), 2) as avg_age
from tb_clk_rcd
join tb_cst_bas_inf using(cust_uid)
where if_buy=1
group by prd_id
order by prd_id
27. 618每一件商品的加购率
明确题意:
统计每一件商品的加购率(加购率:加购次数/访问次数,保留小数点后两位)
问题拆解:
- 统计加购次数。知识点:sum(),按商品分组group by
- 统计访问次数。知识点:sum(),按商品分组group by
- 分组计算加购率。知识点:/,按商品分组group by
- 保留两位小数。知识点:round
- 按prd_id升序排序。知识点:order by
代码实现:
select prd_id, round(sum(if_cart) / sum(if_vw), 2) as cart_rate
from tb_clk_rcd
group by prd_id
order by prd_id
28. 618展示到浏览、浏览到加购、加购到购买的转化率
明确题意:
计算展示到浏览、浏览到加购买、加购到购买的转换率(按照用户数而非点击率算)
问题拆解:
- 分别统计总展示数、总浏览数、总加购数、总购买数,基于用户数。知识点:COUNT(DISTINCT)、IF(if_xxx, cust_uid, NULL)
- 计算各种率。知识点:除法/
代码实现:
SELECT ROUND(vw_cnt / snd_cnt, 2) as `展示到浏览`,
ROUND(cart_cnt / vw_cnt, 2) as `浏览到加购`,
ROUND(buy_cnt / cart_cnt, 2) as `加购到购买`
FROM (
SELECT COUNT(DISTINCT IF(if_snd, cust_uid, NULL)) as snd_cnt,
COUNT(DISTINCT IF(if_vw, cust_uid, NULL)) as vw_cnt,
COUNT(DISTINCT IF(if_cart, cust_uid, NULL)) as cart_cnt,
COUNT(DISTINCT IF(if_buy, cust_uid, NULL)) as buy_cnt
FROM tb_clk_rcd
) as t_cnt
29. 6月份连续3天登录的用户数
明确题意:
统计6月份连续登录至少为3天的用户数
问题拆解:
- 对每个用户每天登录记录去重,一个一个一天只保留一条。知识点:distinct
- 对每个用户的登录日期按顺序编号。知识点:按顺序编号row_number() over(partition by user_id order by login_date);
- 计算每个用户每次连续的登录天数。知识点:按用户ID、登录日期减去序号(即本次连续登录起始日期)分组group by;统计连续签到天数count();
- 筛选连续登录天数大于等于3的记录。知识点:having
- 统计满足上述条件的用户数,注意一个用户可能有多次连续签到满足条件。知识点:count(distinct user_id)
代码实现:
select count(distinct user_id) as num
from (
select user_id, count(*) as continuous_days
from (
select user_id, login_date,
row_number() over(partition by user_id order by login_date) as rn
from (
select distinct user_id, login_date
from logintb
where login_date between "2021-06-01" and "2021-06-30"
) as t_uniq_user_login
) as t_login_rn
group by user_id, DATE_SUB(login_date, INTERVAL rn day)
having continuous_days>=3
) as t_login_ge3
30. 6月2日的T+1日留存
明确题意:
统计6月2日的T+1日留存
问题拆解:
- 筛选20210602登录的用户唯一ID。知识点:where、distinct
- 筛选20210603登录的用户唯一ID。知识点:where、distinct
- 统计0602登录用户在0603的登录状态。知识点:left join
- 计算0602的用户在0603的留存率。知识点:count
- 保留2位小数。知识点:round
代码实现:
select round(count(login_0603) / count(login_0602), 2) as avg_ret
from (
select distinct user_id, 1 as login_0602, login_0603
from logintb
left join (
select distinct user_id, 1 as login_0603
from logintb
where login_date='2021-06-03'
) as t_login_3
using (user_id)
where login_date='2021-06-02'
) as login_02_03
31. 单日登录次数大于等于2次的用户数
明确题意:
统计单日登录次数大于等于2次的用户数
问题拆解:
- 统计单日登录次数。知识点:按用户ID和日期分组group by;统计登录次数count
- 筛选登录次数大于等于2的用户。知识点:having
- 统计满足条件的用户个数。知识点:count(distinct)
代码实现:
select count(distinct user_id) as num
from (
select user_id, login_date, count(1) as login_times
from logintb
group by user_id, login_date
having count(login_times)>=2
) as t_login_times
32. 7月份各时间段的登录情况
明确题意:
统计7月份通勤(7:00-9:00、18:00-20:00),午休(11:00-13:00),临睡(22:00-1:00)时段登录用户数分别是多少
问题拆解:
- 筛选2021年7月的用户登录记录。知识点:where
- 判断每条登录记录是否在通勤、午休、临睡时段。知识点:if(.., 1, null);between and
- 统计每个时段登录的次数。知识点:count()。(如果是统计登录用户数,则需要和user_id一起做distinct)
代码实现:
select
count(if(login_time between "7:0:0" and "9:0:0" or
login_time between "18:0:0" and "20:0:0", 1, null)) as `通勤`,
count(if(login_time between "11:0:0" and "13:0:0", 1, null)) as `午休`,
count(if(login_time between "22:0:0" and "23:59:59" or
login_time between "0:0:0" and "1:0:0", 1, null)) as `临睡`
from login_tb
where login_date between "2021-07-01" and "2021-07-31"
33. 2021年6月份月活
明确题意:
统计2021年6月份的月活
问题拆解:
- 筛选2021年6月份的记录。知识点:where
- 统计月份数。知识点:count(distinct)
代码实现:
select count(distinct user_id) as month_active_user
from logintb
where login_date between "2021-06-01" and "2021-06-30"