SQL 进阶刷题笔记
一、MySQL 进阶
这里主要是 MySQL 刷题相关笔记,方便后面温习和查阅,希望可以帮到大家!!!
题1
请计算每张SQL类别试卷发布后,当天5级以上的用户作答的人数uv和平均分avg_score,按人数降序,相同人数的按平均分升序。
描述
问题分解
- 获取每张SQL类别试卷发布日期,作为子查询:
- 筛选试卷类别:WHERE tag = “SQL”
- 获取试卷ID和发布日期:SELECT exam_id, DATE(release_time)
- 筛选发布当天的作答记录:WHERE (exam_id, DATE(start_time)) IN (…)
- 筛选5级以上的用户:AND uid IN (SELECT uid FROM user_info WHERE level > 5)
- 按试卷ID分组:GROUP BY exam_id
- 计算作答人数:count( DISTINCT uid ) AS uv
- 计算平均分(保留1位小数):ROUND(avg( score ), 1) AS avg_score
完整代码
SELECT
exam_id,
count( DISTINCT uid ) AS uv,
ROUND(avg( score ), 1) AS avg_score
FROM exam_record
WHERE (exam_id, DATE(start_time)) IN (
SELECT exam_id, DATE(release_time)
FROM examination_info WHERE tag = "SQL"
) AND uid IN ( SELECT uid FROM user_info WHERE `level` > 5 )
GROUP BY exam_id
ORDER BY uv DESC, avg_score ASC;
题2
给你一张试卷作答记录表,一张题目练习记录表,请你查询出其中每张试卷和每道题目被作答过的人数和作答的次数,最后按照人数和作答次数的顺序逆序排列
描述
问题分解
- 先统计试卷区每份试卷被回答的人数和次数:
- 以试卷exam_id作为分组,便于统计每份试卷被作答的人数和次数。知识点:group by
- 对于每一组即每一份试卷,统计作答的人数,即uid的数量,要注意去重,即同一人可能回答多次。知识点:count()、distinct
- 对于每一组即每一份试卷,统计被作答次数,只需要统计出现多少次即可,不用去重。知识点:count()
- 对查询结果按照先uv再pv的降序排序,
order by uv desc, pv desc
- 再统计题目区每份试卷被回答的人数和次数:
- 以试卷question_id作为分组,便于统计每个题目被作答的人数和次数。知识点:group by
- 对于每一组即每个题目,统计作答的人数,即uid的数量,要注意去重,即同一人可能回答多次。知识点:count()、distinct
- 对于每一组即每个题目,统计被作答次数,只需要统计出现多少次即可,不用去重。知识点:count()
- 对查询结果按照先uv再pv的降序排序,
order by uv desc, pv desc
- 从试卷区的选择中选出全部与从题目区的选择中选出的全部合并,
select * from () exam union select * from () practice
。知识点:union
完整代码
select * from (
select exam_id as tid,count(distinct uid) uv,count(*) pv
from exam_record
group by exam_id
order by uv desc ,pv desc
) a
union all
select * from (
select question_id as tid,count(distinct uid) uv,count(*) pv
from practice_record
group by question_id
order by uv desc ,pv desc
) b
题3
请写出一个SQL实现:输出2021年里,所有每次试卷得分都能到85分的人以及至少有一次用了一半时间就完成高难度试卷且分数大于80的人的id和活动号,按用户ID排序输出。
描述
问题分解
- 筛选2021年每次试卷得分都大于等于85的人和字符串’activity1’:
- 按照uid进行分组划分,统计每个用户的得分情况。知识点:group by
- 选出提交时间在2021年的试卷。知识点:select…from…where…、year()
- 对于每组要求判断最小得分不小于85。知识点:having、min()
- 筛选2021年至少有一次用了一半时间就完成高难度试卷且分数大于80的人和字符串’activity2’:
- 试卷信息和考试信息分布在两个表中,须将其通过exam_id连接起来。知识点:join…on…
- 从连接后的两个表格中满足四个条件的不重复的用户ID,因为只要求至少一次下述情况(知识点:distinct、where…and…):
- 提交时间是2021年。
year(e_r.submit_time) = 2021
- 试卷难度是困难。
e_i.difficulty = 'hard'
- 得分大于80。
e_r.score > 80
- 只用了试卷要求时间一半不到的时间就完成。
timestampdiff(minute, e_r.start_time, e_r.submit_time) * 2 < e_i.duration
- 提交时间是2021年。
- 将两个筛选合并。知识点:union all
- 按照用户ID排序输出。知识点:order by uid
完整代码
select uid , 'activity1' as activity
from exam_record
where year(submit_time) = 2021
group by uid
having min(score) >= 85
union all
select distinct b.uid, 'activity2' as activity
from examination_info a
join exam_record b on a.exam_id = b.exam_id
where year(b.submit_time) = 2021
and a.difficulty = 'hard'
and b.score > 80
and timestampdiff(minute,b.start_time,b.submit_time) * 2 < a.duration
order by uid
关注林哥,持续更新哦!!!★,°:.☆( ̄▽ ̄)/$:.°★ 。