SQL25 满足条件的用户的试卷完成数和题目练习数
题目主要信息:
- 请找到高难度SQL试卷得分平均值大于80并且是7级红名大佬的2021年试卷完成数和题目练习数
- 用户信息表user_info(uid用户ID,nick_name昵称, achievement成就值, level等级, job职业方向, register_time注册时间)
- 试卷信息表examination_info(exam_id试卷ID, tag试卷类别, difficulty试卷难度, duration考试时长, release_time发布时间)
- 试卷作答记录表exam_record(uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分)
- 题目练习记录表practice_record(uid用户ID, question_id题目ID, submit_time提交时间, score得分)
问题拆分:
- 先找满足2021年高难度试卷平均得分大于80且是7级红名大佬的用户ID:
- 我们要找到每个用户ID满足上述条件,其中平均分肯定要以uid分组。知识点:group by
- 考试得分及提交时间在表exam_record中,试卷信息在表examination_info中,用户信息在表user_info中,我们通过exam_id将前二者连接,再通过uid将用户信息表连在后面。知识点:join...on...
- 从连接后表中选出符合条件的ID。
where tag = 'SQL' and difficulty = 'hard' and year(submit_time) = 2021 and level = 7
- 同时还需要判断平均分,筛选出平均分大于80的。知识点:having、avg()
- 再从上述ID中找到每个用户2021年试卷答题数:
- 从表exam_record中筛选出用户ID在上面筛选出的结果里,且提交时间是2021年的用户ID和每个ID的作答场次。知识点:select...from...where...in...and...
- 求每个ID的作答场次需要以uid为划分进行分组。知识点:group by
- 最后将结果命名为一个新表。
- 最后将找到每个用户的2021年试卷答题数和练习题数:
- 使用left join将新表与practice_record连接,因为筛选出来的新表一定做了试卷,但是不一定做了练习题,left join可以让新表连接全部,practice_record中没有的连接null。 知识点:left join...on...
- 从连接后的表中选出用户ID、每个ID的作答场次、每个ID的练习题目数,需要以uid分组。知识点:group by
- 对每组的作答场次直接选择,练习题数目筛选提交时间是2021年,或者为空(0题)的进行计数。
where year(submit_time) = 2021 or submit_time is null
知识点:count()
- 按照试卷答题数升序、练习题数降序输出。
order by exam_cnt asc, question_cnt desc
代码:
select exam.uid as uid,
exam_cnt,
count(score) as question_cnt
from
(select uid,
count(score) as exam_cnt
from exam_record
where uid in(
select e_r.uid as uid
from exam_record e_r join examination_info e_i
on e_r.exam_id = e_i.exam_id
join user_info u_i
on e_r.uid = u_i.uid
where tag = 'SQL'
and difficulty = 'hard'
and year(submit_time) = 2021
and level = 7
group by e_r.uid
having avg(score) > 80
)
and year(submit_time) = 2021
group by uid) exam
left join practice_record p_r
on exam.uid = p_r.uid
where year(submit_time) = 2021 or submit_time is null
group by uid
order by exam_cnt asc, question_cnt desc