题解 | #统计复旦用户8月练题情况#

统计复旦用户8月练题情况

http://www.nowcoder.com/practice/53235096538a456b9220fce120c062b3

题意明确:

复旦大学的每个用户在8月份练习的总题目数回答正确的题目数情况


问题分解:

  • 限定条件:需要是复旦大学的(来自表user_profile.university),8月份练习情况(来自表question_practice_detail.date)
  • 从date中取month:用month函数即可;
  • 总题目:count(question_id)
  • 正确的题目数:sum(if(qpd.result='right', 1, 0))
  • 按列聚合:需要输出每个用户的统计结果,因此加上group by up.device_id

细节问题:

  • 8月份没有答题的用户输出形式:题目要求『对于在8月份没有练习过的用户,答题数结果返回0』因此明确使用left join即可,即输出up表中复旦大学的所有用户,如果8月没有练习记录,输出0就好了
  • 老样子-表头:as语法重命名后两列就好

完整代码:

select up.device_id, '复旦大学' as university,
    count(question_id) as question_cnt,
    sum(if(qpd.result='right', 1, 0)) as right_question_cnt
from user_profile as up

left join question_practice_detail as qpd
  on qpd.device_id = up.device_id and month(qpd.date) = 8

where up.university = '复旦大学'
group by up.device_id
全部评论
关于month(date)为什么不写在where后面:首先month函数不是聚合函数,是可以写在where语句中的;其次是,如果写在where中,是对连接好的表进行判断,如果是用user表leftjoin question表,由于question表里没有4321用户的记录,那么连接好的表中的id为4321的用户是没有date值的,也就是date为空,所以在执行where month(date)=8的时候会除掉4321这行记录,所以最后的结果里就没有这个id的记录啦!主要是要理解:1.先执行from,再执行where,where中的操作是对连接好的表的操作;2.a左连接b,对于a有而b没有的id,则连接好的表中的这些id的b相关的属性值为空。
103 回复 分享
发布于 2022-01-10 23:14
请问为什么month(date)=8要写在表链接left join语句里,而不是写在后续where中呢?我试了写在where后就是报错
40 回复 分享
发布于 2021-09-17 13:46
当在where子句使用聚合函数时,此时根据group by 分割结果集的子句还没有执行,此时只有from 后的结果集。 所以无法在where子句中使用聚合函数。
9 回复 分享
发布于 2021-10-22 10:26
为什么可以直接 select '复旦大学'阿?
8 回复 分享
发布于 2022-02-02 21:39
牛哇,这个sum(if(result='right',1,0))用法真的太棒了!
7 回复 分享
发布于 2022-05-23 23:01
有些同学纠结on后面跟and的问题。研究了一下发现这之前确实没有在书上看到,但是确有这个规则。 以left join为例,当在on后面使用and,分为两种情况。 第一种是and的过滤语句对左表做过滤时,过滤不生效,强制返回所有左表行。第二种情况是 and的过滤语句对右表做过滤时,过滤生效,对右表过滤后按照原left join的逻辑连接。那么此时NULL仍然会出现,可以视为把条件放在on语句后面提早了执行顺序,提前对右表做了一次子查询的过滤再进行连接,是一个简化的语法。 那么当我们把查询month(qd.date) = 8 放在where 处,则是连接完成后再进行过滤,此时会被NULL过滤掉。
6 回复 分享
发布于 2022-07-28 19:53
请问为什么我把month(date)=8放在where后面,八月没有答题的用户就不能查询出来
5 回复 分享
发布于 2021-11-13 15:23
请问为什么university='复旦大学'的限制条件不能也放在join on里面呢?我试了一下,结果相当于没有筛选学校,这是为什么呢?请赐教
5 回复 分享
发布于 2021-11-13 15:07
为什么正确的题目数是sum而不是count的?count不是用于计数的吗?count(if(qpd.result='right', 1, 0))不也是记录正确的数量吗?谢谢回答啦!
5 回复 分享
发布于 2021-11-12 11:51
为什么第一行有'复旦大学' as university,然后最后还有where up.university = '复旦大学',没太懂,求教,谢谢!
3 回复 分享
发布于 2022-04-09 14:54
为什么group by 后只写了device_id 而没有写university? select 后不是要小于等于group by后的字段吗?
3 回复 分享
发布于 2022-01-06 21:24
count(question_id)不会把8月没有答题的用户过滤掉嘛,count统计不了null值吧,应该用ifnull(count(question_id),0),求解答,谢谢!
3 回复 分享
发布于 2021-11-17 19:19
评论区没看到回答到点子上的,LEFT JOIN 保留左表的所有行,即使右表无匹配项。若ON条件因NULL值无法判断,左表行仍会保留。这就是为什么month(q.date) = 8条件放在on后面可以,而放在where后面却不可以的原因。这是本人博客,更多答案解析在我的博客里面:https://blog.csdn.net/m0_37738114?spm=1011.2266.3001.5343
2 回复 分享
发布于 07-12 23:27 浙江
总题目数不应该要对question_id去重吗, 如果一个人在8月做了同一道题目两次, 应该只能算一个吧
2 回复 分享
发布于 2023-09-29 15:56 北京
数据量很大的话这种写法,在狗东能跑一个多小时
2 回复 分享
发布于 2022-04-22 14:27
为什么month(date)=8放在on后面,不会把date为null的4321给过滤掉?求解答
1 回复 分享
发布于 2024-01-18 20:22 广东
我不太理解为什么要用device_id 分组啊? device_id不是本来就是唯一的吗?
1 回复 分享
发布于 2022-07-06 11:12
为啥这个答案复制到答题板上面会显示错误啊,其他的答案也是这样的
1 回复 分享
发布于 2022-04-03 18:30
小白求问:qpd.result='right', 1, 0里面的1,0是啥意思?
1 回复 分享
发布于 2022-04-01 21:04
不用【'复旦大学' as university】,后面有【where university='复旦大学'】
点赞 回复 分享
发布于 07-03 15:57 山东

相关推荐

真的很糟糕:不一定是你的问题,当然你也可以做的更好一些,继续投相信自己一定会有的
点赞 评论 收藏
分享
野猪不是猪🐗:阿里系官网投递就是这个样子。它不会向tx那样意向组不捞自动共享到全局池子。阿里系你投那个组就只有哪个组能看到。而大部分组是不招人了,所以你什么简历投过去都是挂
投递阿里巴巴集团等公司10个岗位
点赞 评论 收藏
分享
评论
481
92
分享

创作者周榜

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