首先根据以下代码获得初步结果:

select * 
from user_profile u
left JOIN question_practice_detail q

# left join on 后面最好只放两者关联条件,不要放单独条件,
# 例如 “u.university = '复旦大学'”,容易出错
on u.device_id = q.device_id

# 要同时考虑在 8 月答题了和没答题的用户
where u.university = '复旦大学' and (Month(q.date) = '08' or Month(q.date) is null);

结果如下:

2|3214|male|None|复旦大学|4.000|15|5|25|15|3214|113|wrong|2021-08-18
2|3214|male|None|复旦大学|4.000|15|5|25|14|3214|112|wrong|2021-08-16
2|3214|male|None|复旦大学|4.000|15|5|25|9|3214|113|wrong|2021-08-15
7|4321|male|28|复旦大学|3.600|9|6|52|None|None|None|None|None

然后分组求和:

select u.device_id, u.university,
        SUM(if(q.result is not null, 1, 0)) questino_cnt,
        SUM(if(q.result = 'right', 1, 0)) right_question_cnt 
from user_profile u
left JOIN question_practice_detail q

# left join on 后面最好只放两者关联条件,不要放单独条件,
# 例如 “u.university = '复旦大学'”,容易出错
on u.device_id = q.device_id

# 要同时考虑在 8 月答题了和没答题的用户
where u.university = '复旦大学' and (Month(q.date) = '08' or Month(q.date) is null)
group by u.device_id;