题解 | #试卷完成数同比2020年的增长率及排名变化#

试卷完成数同比2020年的增长率及排名变化

http://www.nowcoder.com/practice/13415dff75784a57bedb6d195262be7b

问题的关键在于最后一个字段排序的变化问题。题目字段默认的是digint(整数类型)为unsigned 类型。

如果直接用21的排名-20的排名,就会出现一个错误是:digint unsigned value is out of range in(exam_cnt_rank_21-exam_cnt_rank_20... )之类的。大概意思就是数据默认定义的digint类型是unsigned,unsigned和signed的区别在于unsigned是非负数,也就是默认只能为正数和0,本题中会出现21年排名-20年排名为负数的情况,所以需要使用if函数,这样的方法来修正可能会出现负数的情况

if(exam_cnt_rank_21>=exam_cnt_rank_20,exam_cnt_rank_21-exam_cnt_rank_20,(-(exam_cnt_rank_20-exam_cnt_rank_21))) exam_delta 

内心OS(其实mysql这一些列的题目都很好,但是在进阶的部分我作为菜鸟新手,不明白为什么题目的描述会那么容易让人产生歧义,并且给到的范例数据和答案往往都不说清楚埋藏的陷阱,非要让你自己去瞎猜,例如本题三个雷

第一个就是最后的这个unsigned,实在是不明白最后这里放个这个目的是啥???

第二个是给到的表格数据里面每个用户id在每一天做的试卷id都不同,不是简单的根据试卷id分组求和就完了,相当于题目默认是同一个用户同一天可能会做好几次同一份试卷,但是计算数值时只能计算一次???(这个因为之前被坑的太多次所以这个没被坑到)

第三个是给的事例答案最后一个字段排名的变化是正值,“排名1=>2,后退1名。”这都是啥?然后给到的答案表格里确是正1,实际最后做题的时候非要给你搞一个负值的情况???)

不知道有多少刷题刷到这里的朋友跟我有一样的感悟... 还有一些大神也会在解答区分享自己的代码和思想,觉得他们思维逻辑真的很厉害,如果对书写规范更精进一些的话就更完美了。

本人也是小白看视频刷题,都是自己摸索,书写规范也是查了一些资料然后根据自己的理解写的,希望大家读起来能更容易更简单一些。其他部分的代码其实都很简单,我写的也不够简练,大家应该也不用参考。以上。

SELECT tag, exam_cnt_20, exam_cnt_21, 
CONCAT(ROUND((exam_cnt_21-exam_cnt_20)*100/exam_cnt_20,1),'%') growth_rate,
exam_cnt_rank_20, exam_cnt_rank_21,
IF(exam_cnt_rank_21>=exam_cnt_rank_20,
	exam_cnt_rank_21-exam_cnt_rank_20,
    (-(exam_cnt_rank_20-exam_cnt_rank_21))
    ) rank_delta
 FROM
	(SELECT exam_id, SUM(c1) exam_cnt_20, 
    RANK() OVER(ORDER BY SUM(c1) DESC) exam_cnt_rank_20 from
		(SELECT exam_id, uid, 
		COUNT(DISTINCT CASE WHEN date_format(submit_time,'%y%m%d') 
        		BETWEEN '200101' AND '200630' 
      			THEN date_format(submit_time,'%y%m%d') 
                END) c1
		FROM exam_record 
		GROUP BY exam_id, uid
 		) r1 
 	GROUP BY exam_id
 	HAVING exam_cnt_20<>0
 	) r2 
 JOIN
	(SELECT exam_id, SUM(c1) exam_cnt_21, 
    RANK() OVER(ORDER BY SUM(c1) DESC) exam_cnt_rank_21 
    FROM
		(SELECT exam_id, uid, 
		COUNT(DISTINCT CASE WHEN date_format(submit_time,'%y%m%d') 
        		BETWEEN '210101' AND '210630' 
      			THEN date_format(submit_time,'%y%m%d') 
                END) c1
		FROM exam_record 
		GROUP BY exam_id, uid
 		) r1 
 	GROUP BY exam_id
 	HAVING exam_cnt_21<>0
 	) r3 
 ON r2.exam_id=r3.exam_id
 JOIN examination_info ei ON r2.exam_id=ei.exam_id
 ORDER BY growth_rate DESC, rank_delta DESC

全部评论

相关推荐

面试摇了我吧:啊哈哈面试提前五个小时发,点击不能参加就是放弃
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务