题解 | #满足条件的用户的试卷完成数和题目练习数#

满足条件的用户的试卷完成数和题目练习数

http://www.nowcoder.com/practice/5c03f761b36046649ee71f05e1ceecbf

其实看到这道题,我一开始满脑子在想,怎么结合在一起,因为条件基本顺从于exam_record这张表,结果写得非常复杂且不正确

后面我想了下,为啥不能先把这些数据表先做简化呢

于是第一步,我先从统计那步下手,分别将exam_record完成试卷数 practice_record题目练习数一一算出来
select 
    uid,
    count(submit_time) as exam_cnt
from exam_record
where YEAR(submit_time) = 2021
group by uid
select
    uid,
    count(submit_time) as question_cnt
from practice_record
where YEAR(submit_time) = 2021
group by uid

第二步,我着重于它的筛选条件“高难度SQL试卷得分平均值大于80并且是7级的红名大佬
这步其实针对于exam_record,user_info,examination_info这三张表,后两者只是用于连接作用,因此难度并不大
需要注意的是,该SQL只查询Uid是为了后续的衔接,加上其他字段并无太大实际作用
select
    uid
from exam_record
join examination_info using(exam_id)
join user_info using(uid)
where tag = 'SQL' and difficulty = 'hard' and `level` = 7
group by uid
having avg(score) >= 80

第三步,前者条件也筛选出来了,后者试卷数和练习数也写出来了,只剩下组装这项工程了
试卷数和练习数的SQL语句里面留下uid这个字段,目的就是链接三者
下面为最终SQL语句
select 
    uid,
    exam_cnt,
    if(question_cnt is null, 0, question_cnt)
from
(select 
    uid,
    count(submit_time) as exam_cnt
from exam_record
where YEAR(submit_time) = 2021
group by uid) t

left join

(select
    uid,
    count(submit_time) as question_cnt
from practice_record
where YEAR(submit_time) = 2021
group by uid) t2 using(uid)

where uid in
(
select
    uid
from exam_record
join examination_info using(exam_id)
join user_info using(uid)
where tag = 'SQL' and difficulty = 'hard' and `level` = 7
group by uid
having avg(score) >= 80
)
order by exam_cnt asc, question_cnt desc




全部评论
这里可以用子查询吗
1 回复 分享
发布于 2022-01-21 10:05
结构化思想的典范,逻辑明晰,水晶般透明。
11 回复 分享
发布于 2021-12-22 23:19
思路很清晰。至于为什么最后会是left join,是因为题目中有这样一句话‘只保留2021年有试卷完成记录的用户’。如果不加入这个条件,我觉得应该用full join。 然后select里面的两个数量,都需要用ifnull来判断。如果理解不对,请告知。
6 回复 分享
发布于 2022-04-29 05:33
having avg(score) > 80
5 回复 分享
发布于 2022-02-23 17:07
如果只练习 不考试,是不是exam_record left join practice_record 就没有数字了,是否考虑用union all 两个表,然后sum
3 回复 分享
发布于 2022-03-10 09:12
对不起,我是新手,有一个点我不是很理解,就是那个平均分为什么不可以在where and里面过滤呀?可以指点一下吗,十分感谢
2 回复 分享
发布于 2022-03-30 23:05
牛哇牛哇
1 回复 分享
发布于 2022-11-06 11:42 四川
where tag = 'SQL' and difficulty = 'hard' and `level` = 7 这一句用什么要在level字段上加单引号呢,不加还会报错,没理解
1 回复 分享
发布于 2022-11-01 10:06 北京
大佬,你前面两个表的拼接为什么要用left join而不是right join呢?,也会存在有的用户没做试卷但是做了习题呀?
1 回复 分享
发布于 2022-06-23 16:29
question_cnt这里为什么要用到if函数呢 if(question_cnt is null, 0, question_cnt)
1 回复 分享
发布于 2022-01-29 13:27
就没人复制之后结果会多出个uid是1006的数据?
点赞 回复 分享
发布于 2024-12-29 15:58 浙江
为什么不能把四张表都join后再过滤呢?
点赞 回复 分享
发布于 2024-04-18 14:36 上海
点赞 回复 分享
发布于 2023-12-06 16:30 重庆
查询的过程,在进行表之间的连接时,不可以使用on(相同字段名), 只能使用using(相同字段名), 想请问下有那个大佬知道是什么原因吗? 两者不是都可以嘛? 而且using的限制比起on更大把?
点赞 回复 分享
发布于 2023-09-28 05:27 爱尔兰
为什么是左连接,假如右表的人数比左表的人数多呢?应该是全外连接吧?但是mysql又不支持full outer join,求解惑
点赞 回复 分享
发布于 2023-09-06 18:41 北京
我这样写 难道不对吗 select a.uid, exam_cnt, if(question_cnt is null, 0, question_cnt) as question_cnt from ( select uid, count(exam_id) as exam_cnt from exam_record where uid in ( select uid from exam_record er join user_info ui using(uid) join examination_info ei using(exam_id) where tag = 'SQL' and difficulty = 'hard' and year(submit_time) = 2021 and `level` = 7 group by uid having avg(score) >= 80) group by uid ) a left join ( select uid, count(question_id) as question_cnt from practice_record where uid in ( select uid from exam_record er join user_info ui using(uid) join examination_info ei using(exam_id) where tag = 'SQL' and difficulty = 'hard' and year(submit_time) = 2021 and `level` = 7 group by uid having avg(score) >= 80) group by uid ) b on a.uid = b.uid order by exam_cnt asc, question_cnt desc 为啥运行不通过...
点赞 回复 分享
发布于 2023-05-22 13:58 未知
向大家请教个问题,举个例子:如果exam_record表里面不存在uid为1003的记录,这样的话使用上面代码最后统计出来的记录里是不是也不含uid为1003的记录。所以这个代码只是针对题目中的例子是对的?
点赞 回复 分享
发布于 2023-04-17 11:38 江苏
解题思路清晰,答案赞。if可以简化下哈 ifnull(question_cnt,0)
点赞 回复 分享
发布于 2023-03-13 23:33 北京
有一点想问一下大佬,为什么查考试完成数的时候,count(submit_time)是对的,而count(uid)不行
点赞 回复 分享
发布于 2023-01-12 10:26 广东
SELECT uid,exam_cnt,question_cnt FROM ( SELECT er.uid, -- er.exam_id, COUNT(er.submit_time) AS exam_cnt, COUNT(pr.submit_time) AS question_cnt, AVG(er.score) AS er_score FROM exam_record er JOIN practice_record pr ON er.uid=pr.uid LEFT JOIN user_info ui ON ui.uid=er.uid LEFT JOIN examination_info ei ON ei.exam_id=er.exam_id WHERE tag='SQL' AND difficulty ='hard' AND YEAR(er.submit_time)='2021' AND ui.level='7' GROUP BY er.uid -- ,er.exam_id HAVING AVG(er.score)>80 )t ORDER BY exam_cnt ASC,question_cnt DESC; 为什么不能这么写,既然都是group by uid
点赞 回复 分享
发布于 2022-09-27 19:34 浙江

相关推荐

码农索隆:这种hr,建议全中国推广
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-04 14:35
点赞 评论 收藏
分享
评论
283
33
分享

创作者周榜

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