明确题意:
找到高难度SQL试卷得分平均值大于80并且是7级的红名大佬,统计他们的2021年试卷完成数和题目练习数; 结果按试卷完成数升序,按题目练习数降序。
问题分解:
- 找出高难度SQL试卷得分平均值大于80分的7级用户,生成子表t_user_id:
- 内连接试卷作答表、试卷信息表、用户信息表:exam_record JOIN examination_info USING(exam_id) JOIN user_info USING(uid)
- 筛选出目标用户:WHERE difficulty='hard' and tag='SQL' and
level
=7 - 按用户分组:GROUP BY uid
- 筛选平均分大于80的分组(用户):HAVING AVG(score)>80
- 统计每个用户2021年的试卷完成数,生成子表t_exam_cnt:
- 筛选作答时间和已完成:WHERE YEAR(submit_time)=2021 AND submit_time IS NOT NULL
- 按用户分组:GROUP BY uid
- 统计试卷完成数:count(exam_id) as exam_cnt
- 统计每个用户2021年的试题作答数,生成子表t_question_cnt:
- 筛选作答时间:WHERE YEAR(submit_time)=2021
- 按用户分组:GROUP BY uid
- 统计试题作答数:count(question_id) as question_cnt
- 关联三张表:
- 内连接t_user_id和t_exam_cnt,因为用户属性条件必须满足,题目又要求了只输出有试卷完成记录的用户:t_user_id JOIN t_exam_cnt USING(uid)
- 左连接t_question_cnt:因为只要满足上面条件的结果,即使无试题作答记录也输出:LEFT JOIN t_question_cnt USING(uid)
- 特殊处理试题作答数可能为0的情况(此时关联结果中试题作答数为NULL):IFNULL(question_cnt, 0) as question_cnt
细节问题:
- 表头重命名:as
- 按试卷完成数升序、题目练习数降序:ORDER BY exam_cnt, question_cnt desc
完整代码:
SELECT uid, exam_cnt, IFNULL(question_cnt, 0) as question_cnt
FROM (
SELECT uid
FROM exam_record
JOIN examination_info USING(exam_id)
JOIN user_info USING(uid)
WHERE difficulty='hard' and tag='SQL' and `level`=7
GROUP BY uid
HAVING AVG(score)>80
) as t_user_id
JOIN (
SELECT uid, count(exam_id) as exam_cnt
FROM exam_record
WHERE YEAR(submit_time)=2021 AND submit_time IS NOT NULL
GROUP BY uid
) as t_exam_cnt
USING(uid)
LEFT JOIN (
SELECT uid, count(question_id) as question_cnt
FROM practice_record WHERE YEAR(submit_time)=2021
GROUP BY uid
) as t_question_cnt
USING(uid)
ORDER BY exam_cnt, question_cnt desc;