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"

试卷链接:https://docs.qq.com/doc/DRm9mSEd6anRlQm9C

全部评论

相关推荐

03-15 14:55
已编辑
门头沟学院 golang
bg:双非学院本&nbsp;ACM银&nbsp;go选手timeline:3.1号开始暑期投递3.7号第二家公司离职顽岩科技&nbsp;ai服务中台方向&nbsp;笔试➕两轮面试,二面挂(钱真的好多😭)厦门纳克希科技&nbsp;搞AI的,一面OC猎豹移动&nbsp;搞AIGC方向&nbsp;一面OC北京七牛云&nbsp;搞AI接口方向&nbsp;一面OC上海古德猫宁&nbsp;搞AIGC方向&nbsp;二面OC上海简文&nbsp;面试撞了直接拒深圳图灵&nbsp;搞AIGC方向一面后无消息懒得问了,面试官当场反馈不错其他小厂没记,通过率80%,小厂杀手😂北京字节&nbsp;具体业务不方便透露也是AIGC后端方向2.28约面&nbsp;(不知道怎么捞的我,我也没在别的地方投过字节简历哇)3.6一面&nbsp;一小时&nbsp;半小时拷打简历(主要是AIGC部分)剩余半小时两个看代码猜结果(经典go问题)➕合并二叉树(秒a,但是造case造了10分钟哈哈)一天后约二面3.12&nbsp;二面,让我挑简历上两个亮点说,主要说的docker容器生命周期管理和raft协议使用二分法优化新任leader上任后与follower同步时间。跟面试官有共鸣,面试官还问我docker底层cpu隔离原理和是否知道虚拟显存。之后一道easy算法,(o1空间解决&nbsp;给定字符串含有{和}是否合法)秒a,之后进阶版如何用10台机加快构建,想五分钟后a出来。面试官以为45分钟面试时间,留了18分钟让我跟他随便聊,后面考了linux&nbsp;top和free的部分数据说什么意思(专业对口了只能说,但是当时没答很好)。因为当时手里有7牛云offer,跟面试官说能否快点面试,马上另外一家时间到了。10分钟后约hr面3.13,上午hr面,下午走完流程offer到手3.14腾讯技术运营约面,想直接拒😂感受:&nbsp;因为有AIGC经验所以特别受AI初创公司青睐,AIGC后端感觉竞争很小(指今年),全是简历拷打,基本没有人问我八股(八股吟唱被打断.jpeg),学的东西比较广的同时也能纵向深挖学习,也运气比较好了哈哈可能出于性格原因,没有走主流Java路线,也没有去主动跟着课写项目,项目都是自己研究和写的哈哈
烤点老白薯:你根本不是典型学院本的那种人,贵了你这能力
查看7道真题和解析
点赞 评论 收藏
分享
qq乃乃好喝到咩噗茶:神人哆哆鲤还活着呢,什么时候给这玩意举报下架
点赞 评论 收藏
分享
评论
点赞
7
分享

创作者周榜

更多
牛客网
牛客企业服务