题解 | #统计每个学校各难度的用户平均刷题数#
统计每个学校各难度的用户平均刷题数
https://www.nowcoder.com/practice/5400df085a034f88b2e17941ab338ee8
SELECT
`university`,
`difficult_level`,
ROUND(
COUNT(*) / COUNT(DISTINCT `question_practice_detail`.`device_id`),
4
) AS `avg_answer_cnt`
FROM
`question_practice_detail`
LEFT JOIN `question_detail` ON `question_practice_detail`.`question_id` <=> `question_detail`.`question_id`
LEFT JOIN `user_profile` ON `user_profile`.`device_id` <=> `question_practice_detail`.`device_id`
GROUP BY
`university`,
`difficult_level`;
首先给出了完整语句,接下来分析语句的执行。根据基础知识,上述共涉及到 SELECT 语句的 FROM、GROUP BY、ON 三大子句,执行顺序分别是:FROM -> LEFT JOIN -> ON -> GROUP BY -> [COUNT、DISTINCT] -> SELECT。
初始表一共有三个,本题乍一看很复杂,仔细分析其实就是三表的合并,在这里选用了左外连接,使用题库练习明细表(question_practice_detail)作为基准表,将其中的 device_id 与 question_id 列替换为真实信息。
为什么要选择题库练习明细表作为基准表呢?通过观察可以发现,user_profile 表与 question_detail 表之间并无实际联系,将其任一作为基准表,都会使三个表中恒有一个表无法有效连接。而题库练习明细表中的 device_id 列与 user_profile 表有关;question_id 列与question_detail 表有关,使用它作为基准表是非常合适的。接下来请看演示。
原表
第一次左外连接后
第二次左外连接后
分组函数第一次分组
分组函数第二次分组
此时回看题目:
请你写一个SQL查询,计算不同学校、不同难度的用户平均答题量,根据示例,你的查询应返回以下结果(结果在小数点位数保留4位,4位之后四舍五入)
截至目前,不同学校 & 不同难度 的要求已经满足,那么用户平均答题量如何求得呢?小学数学,用答题总量除以答题用户数即可求得。以“第四分组”为例,共有2个用户,答题9次,四舍五入保留4位小数:9 ÷ 2 = 4.5000,符合预期输出。
那么,此时就需要统计每个分组的数量以及人数,前者使用 COUNT 关键字实现,而后者还需要再分组一次,此处使用 DISTINCT 关键字最佳。
