题解 | 统计每个学校各难度的用户平均刷题数

统计每个学校各难度的用户平均刷题数

https://www.nowcoder.com/practice/5400df085a034f88b2e17941ab338ee8

select u1.university,
q3.difficult_level,
round(count(q3.id)/count(DISTINCT u1.device_id),4) as avg_answer_cnt
from question_practice_detail q2
left join user_profile u1 on q2.device_id=u1.device_id
left join question_detail q3 on q2.question_id=q3.question_id
group by u1.university ,q3.difficult_level
order by u1.university ,q3.difficult_level;

COUNT(qpd.id):统计这一组里总共有多少条答题记录(即总共答了多少题)。
COUNT(DISTINCT u.device_id):统计这一组里有多少个不同的用户(因为一个用户可能答多题,要去重)。
两者相除:平均每个用户答了多少题(按大学+难度分组)。
ROUND(..., 4):保留 4 位小数,让结果更整洁。
AS avg_answer_cnt:给这个计算结果起个名字,叫“平均答题次数”。
✅ 举个例子:
如果“清华大学”的学生一共答了 1000 道“困难题”,而这些题是由 200 个不同学生答的,
那么 avg_answer_cnt = 1000 / 200 = 5.0000 —— 平均每人答了 5 道困难题。
第六步:ORDER BY u.university, qd.difficult_level
作用:把结果按大学字母顺序排,同一所大学内再按难度排序(比如 easy → medium → hard)。
通俗理解:让结果看起来整齐,方便阅读。
✅ 总结一句话:
这条 SQL 的目的是:统计每所大学的学生,在不同难度题目下的平均答题数量(人均答了几道题)。
🧠 小贴士
COUNT(qpd.id) 可以换成 COUNT(*),效果一样(只要 qpd.id 不为 NULL)。
如果某大学没人答某种难度的题,这组就不会出现在结果里(因为没数据可 JOIN)。
使用 COUNT(DISTINCT device_id) 是为了防止重复计算同一个用户。
希望这个解释清晰易懂!如果你有表结构或想改需求,也可以继续问我 😊






SELECT
    u.university,
    qd.difficult_level,
    ROUND(COUNT(qpd.id) / COUNT(DISTINCT u.device_id), 4) AS avg_answer_cnt
FROM
    user_profile u
JOIN
    question_practice_detail qpd ON u.device_id = qpd.device_id
JOIN
    question_detail qd ON qpd.question_id = qd.question_id
GROUP BY
    u.university, qd.difficult_level
ORDER BY
    u.university, qd.difficult_level;
结合图中表格,解释一下这个SQL语句的,每一行的用法,每执一个SQL语句并,展示图的变化,并标记执行顺序,用通俗易懂的话术来解答
Qwen3-Max
太好了!你提供了三张表的数据,我们结合具体数据来一步一步执行这个 SQL 语句,并用“图示变化”和通俗语言解释每一步发生了什么。
🧩 先回顾一下三张表
✅ 表1:user_profile(用户信息)
表格
id	device_id	gender	age	university	gpa	active_days_within_30	question_cnt	answer_cnt
1	2138	male	21	北京大学	3.4	7	2	12
2	3214	male	25	复旦大学	4.0	15	5	25
3	6543	female	20	北京大学	3.2	12	3	30
4	2315	female	23	浙江大学	3.6	5	1	2
5	5432	male	25	山东大学	3.8	20	15	70
6	2131	male	28	山东大学	3.3	15	7	13
7	4321	male	28	复旦大学	3.6	9	6	52
每个用户有一个 device_id,代表他的设备号。
✅ 表2:question_practice_detail(答题记录)
表格
id	device_id	question_id	result
1	2138	111	wrong
2	3214	112	wrong
3	3214	113	wrong
4	6543	111	right
5	2315	115	right
6	2315	116	right
7	2315	117	wrong
8	5432	117	wrong
9	5432	112	wrong
10	2131	113	right
11	5432	113	wrong
12	2315	115	right
13	2315	116	right
14	2315	117	wrong
15	5432	117	wrong
16	5432	112	wrong
17	2131	113	right
18	5432	113	wrong
19	2315	117	wrong
20	5432	117	wrong
21	5432	112	wrong
22	2131	113	right
23	5432	113	wrong
记录了每个用户(通过 device_id)做了哪些题(question_id),以及对错情况。
✅ 表3:question_detail(题目详情)
表格
id	question_id	difficult_level
1	111	hard
2	112	medium
3	113	easy
4	115	easy
5	116	medium
6	117	easy
告诉我们每道题的难度。
🔁 执行顺序(逻辑顺序)
FROM + JOIN → 连接三张表
GROUP BY → 按大学+难度分组
SELECT → 计算平均答题数
ORDER BY → 排序输出
🚀 一步步执行并展示“图的变化”
📌 第一步:FROM user_profile u
只有用户信息表,暂时没变。
✅ 当前数据:7 条用户记录
表格
id	device_id	university	...
1	2138	北京大学	...
2	3214	复旦大学	...
...	...	...	...
📌 第二步:JOIN question_practice_detail qpd ON u.device_id = qpd.device_id
把用户的答题记录关联进来,匹配 device_id
📌 举个例子:
用户 device_id=2138 在 qpd 中有 1 条记录(id=1,题111)
用户 device_id=3214 有 2 条记录(id=2,3)
用户 device_id=6543 有 1 条记录(id=4)
用户 device_id=2315 有 6 条记录(id=5~14)
用户 device_id=5432 有 8 条记录(id=8~23)
用户 device_id=2131 有 3 条记录(id=10,17,22)
用户 device_id=4321 ❌ 没有答题记录 → 被过滤掉!
✅ 所以最终连接后得到:
表格
u.id	u.device_id	u.university	qpd.id	qpd.question_id	result
1	2138	北京大学	1	111	wrong
2	3214	复旦大学	2	112	wrong
2	3214	复旦大学	3	113	wrong
3	6543	北京大学	4	111	right
4	2315	浙江大学	5	115	right
4	2315	浙江大学	6	116	right
4	2315	浙江大学	7	117	wrong
4	2315	浙江大学	12	115	right
4	2315	浙江大学	13	116	right
4	2315	浙江大学	14	117	wrong
4	2315	浙江大学	19	117	wrong
5	5432	山东大学	8	117	wrong
5	5432	山东大学	9	112	wrong
5	5432	山东大学	11	113	wrong
5	5432	山东大学	15	117	wrong
5	5432	山东大学	16	112	wrong
5	5432	山东大学	20	117	wrong
5	5432	山东大学	21	112	wrong
5	5432	山东大学	18	113	wrong
5	5432	山东大学	23	113	wrong
6	2131	山东大学	10	113	right
6	2131	山东大学	17	113	right
6	2131	山东大学	22	113	right
✅ 总共:1 + 2 + 1 + 6 + 8 + 3 = 21 条记录
❌ device_id=4321(复旦大学)没有答题记录 → 被丢弃
📌 第三步:JOIN question_detail qd ON qpd.question_id = qd.question_id
再把每道题的难度加进来
比如:
题111 → hard
题112 → medium
题113 → easy
题115 → easy
题116 → medium
题117 → easy
现在每一行都有:
用户大学
答题记录
题目难度
✅ 最终连接后的数据(只列出关键字段):
表格
u.university	qpd.question_id	qd.difficult_level	qpd.id
北京大学	111	hard	1
复旦大学	112	medium	2
复旦大学	113	easy	3
北京大学	111	hard	4
浙江大学	115	easy	5
浙江大学	116	medium	6
浙江大学	117	easy	7
浙江大学	115	easy	12
浙江大学	116	medium	13
浙江大学	117	easy	14
浙江大学	117	easy	19
山东大学	117	easy	8
山东大学	112	medium	9
山东大学	113	easy	11
山东大学	117	easy	15
山东大学	112	medium	16
山东大学	117	easy	20
山东大学	112	medium	21
山东大学	113	easy	18
山东大学	113	easy	23
山东大学	113	easy	10
山东大学	113	easy	17
山东大学	113	easy	22
✅ 总共还是 21 条记录,但每条都带了难度
📌 第四步:GROUP BY u.university, qd.difficult_level
按 大学 + 难度 分组
我们来看每一组有哪些数据:
🟦 组1:北京大学 + hard
有 2 条记录(题111,来自两个用户)
用户:2138(男)、6543(女)
🟦 组2:北京大学 + easy
没有记录 → 不出现
🟦 组3:复旦大学 + medium
有 1 条记录(题112)
用户:3214
🟦 组4:复旦大学 + easy
有 1 条记录(题113)
用户:3214
注意:虽然用户3214答了两道题,但分别属于不同难度,所以分成两组
🟦 组5:浙江大学 + easy
有 5 条记录(题115、117,多次)
用户:2315(只一个用户)
🟦 组6:浙江大学 + medium
有 2 条记录(题116)
用户:2315
🟦 组7:山东大学 + easy
有 10 条记录(题113、117)
用户:5432(7次)、2131(3次)→ 2 个不同用户
🟦 组8:山东大学 + medium
有 4 条记录(题112)
用户:5432(4次)
📌 第五步:SELECT ...
计算每组的:
sql

编辑



ROUND(COUNT(qpd.id) / COUNT(DISTINCT u.device_id), 4)
✅ 逐组计算:
✅ 北京大学 + hard
COUNT(qpd.id) = 2(两条记录)
COUNT(DISTINCT u.device_id) = 2(两个用户:2138 和 6543)
平均 = 2 / 2 = 1.0000
✅ 复旦大学 + medium
COUNT(qpd.id) = 1
COUNT(DISTINCT u.device_id) = 1(只有3214)
平均 = 1 / 1 = 1.0000
✅ 复旦大学 + easy
COUNT(qpd.id) = 1
COUNT(DISTINCT u.device_id) = 1
平均 = 1 / 1 = 1.0000
✅ 浙江大学 + easy
COUNT(qpd.id) = 5
COUNT(DISTINCT u.device_id) = 1(只有2315)
平均 = 5 / 1 = 5.0000
✅ 浙江大学 + medium
COUNT(qpd.id) = 2
COUNT(DISTINCT u.device_id) = 1
平均 = 2 / 1 = 2.0000
✅ 山东大学 + easy
COUNT(qpd.id) = 10
COUNT(DISTINCT u.device_id) = 2(5432 和 2131)
平均 = 10 / 2 = 5.0000
✅ 山东大学 + medium
COUNT(qpd.id) = 4
COUNT(DISTINCT u.device_id) = 1(只有5432)
平均 = 4 / 1 = 4.0000
📌 第六步:ORDER BY u.university, qd.difficult_level
按大学排序,同一大学内按难度排序(easy → medium → hard)
✅ 最终结果
表格
university	difficult_level	avg_answer_cnt
北京大学	hard	1.0000
复旦大学	easy	1.0000
复旦大学	medium	1.0000
浙江大学	easy	5.0000
浙江大学	medium	2.0000
山东大学	easy	5.0000
山东大学	medium	4.0000
🎯 总结:这条 SQL 是在做什么?
统计每所大学的学生,在不同难度题目上的“人均答题次数”
为什么是“人均”?因为用了 COUNT(DISTINCT u.device_id) 除以总答题数。
为什么有些大学没出现?比如“复旦大学”只出现在 easy 和 medium,因为没人答 hard 题。
为什么“浙江大学”的 easy 题人均答了 5 次?因为只有一个用户(2315)答了 5 次 easy 题。
💡 小贴士
如果你想看“每个用户平均答了多少题”,可以用 user_profile 的 answer_cnt 字段,但这里是看“不同难度下的答题行为”,所以要用明细表。
device_id 是关键连接字段,相当于“身份证号”。
difficult_level 是从 question_detail 表来的,不能直接查。
希望这个图文结合、一步步演示的方式让你彻底理解了这条 SQL 的执行过程!如果想看某个大学的详细数据,也可以继续问我 😊

全部评论

相关推荐

白火同学:1、简历可以浓缩成一页,简历简历先要“简”方便HR快速过滤出有效信息,再要“历”用有效信息突出个人的含金量。 2、教育背景少了入学时间~毕业时间,HR判断不出你是否为应届生。 3、如果你的平台账号效果还不错,可以把账号超链接或者用户名贴到对应位置,一是方便HR知道你是具体做了什么内容的运营,看到账号一目了然,二是口说无凭,账号为证,这更有说服力。
面试被问期望薪资时该如何...
点赞 评论 收藏
分享
01-09 17:12
四川大学 Java
叁六玖:上次建行给我开25万,让我扣2办理
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务