SQL小白来写一下看过答案后的复盘思路。
根据题意:

查询出来的第一列是年月,所以需要用到时间格式化函数【date_format】,即
date_format(submit_time,%y%d) as month
查询出来的第二列是每月用户活跃天数除以每月活跃用户数。
查询出来的第三列是每月活跃用户数。
下面我们依次分析每一列该如何用SQL实现。

根据题意,很容易知道我们需要根据时间【年月】来分组,所以我们先把exam_record表按年月分组展示成集合的形式。注意:集合思想!
按照题目解释,需要排除未作答的记录(submit_time is not null and year(submit_time)= 2021),所以得出以下结果。
202107分组下的集合元素有:
    1 1001 9001 2021-07-02 09:01:01 2021-07-02 09:21:01 80
    5 1002 9001 2021-07-02 19:01:01 2021-07-02 19:30:01 82
    6 1002 9002 2021-07-05 18:01:01 2021-07-05 18:59:02 90
202109分组下的集合元素有:
    2 1002 9001 2021-09-05 19:01:01 2021-09-05 19:40:01 81
    8 1003 9003 2021-09-07 10:01:01 2021-09-07 10:31:01 86
    10 1002 9003 2021-09-01 12:01:01 2021-09-01 12:31:01 81
    11 1005 9001 2021-09-01 12:01:01 2021-09-01 12:31:01 81
    12 1006 9002 2021-09-02 12:01:01 2021-09-02 12:31:01 81
202107月,用户1002活跃了两天,分别是2021-07-02和2021-07-05;用户1001活跃了一天,为2021-07-02,所以202107月共活跃用户2个,共活跃天数3天。
SQL实现为:
202107活跃用户数
    count(distinct uid)
202107活跃天数(按照用户和时间两个约束确定天数)
    count(distinct uid,date_format(submit_time,'%y%m%d')
202107月活跃天数
    count(distinct uid,date_format(submit_time,'%y%m%d')/count(distinct uid)
保留两位小数
round(count(distinct uid,date_format(submit_time,'%y%m%d')/count(distinct uid),2)
综上分析,SQL代码为:
select
    date_format(submit_time,'%Y%m') as month,
    round(count(distinct uid,date_format(submit_time,'%Y%m%d'))/count(distinct uid),2) as avg_active_days,
    count(distinct uid) as mau
from exam_record
where submit_time is not null and year(submit_time) = 2021
group by date_format(submit_time,'%Y%m')