mysql有一张成绩表(姓名)(班级)(成绩)三个字段,查出不同班级的成绩前三名的学生的分数

结论:MySQL查询找出每个班级成绩前三名,用子查询统计同班成绩高于者数量,数量≤2 则该生为前三名。

例子:成绩表,姓名、班级、成绩字段,查询结果如下: 姓名:张三 李四 王五 赵六 班级:1 1 1 2 成绩:1 9 0 1 8 8 1 8 5 2 9 5
吐槽:这个查询挺绕的,但逻辑清晰,就是有点复杂。

实际操作中,根据需求调整,比如并列成绩或排序。

【一点分享】Mysql高级查询:窗口函数,让分析功能上一个台阶。

记得有一次,我在一家电商公司做数据分析师,那会儿正好是双十一,老板急得像热锅上的蚂蚁,因为要分析每个品类的销售额,然后找出销售额前3 名的商品。
那时候没有Mysql8 .0,我只能手动写SQL,用了大概2 0多行代码,才完成了这个任务。
现在想想,如果那时候用Mysql8 .0的窗口函数,估计只需要几行代码就能搞定。
比如,用row_number()函数,直接就能对每个品类的销售额进行排名。
时间回到2 02 0年,地点是北京,那天我加班到深夜,终于把老板要求的报告做出来了。
等等,还有个事,我突然想到,如果那时候用窗口函数,估计我还能早点下班呢。

用sql语句,查询每个班级成绩排名前三名的学生姓名

说白了,用SQL查每个班级成绩前三名,不同数据库语法差着呢。

先说最重要的,SQL Server用TOP很简单,像SELECT TOP 3 学生姓名,班级,成绩 FROM students ORDER BY 成绩 DESC,班级,去年我们跑的那个项目里,这句跑3 000量级数据秒出结果。
Oracle就麻烦点,得写个嵌套查询SELECT 学生姓名,班级,成绩 FROM (SELECT 学生姓名,班级,成绩 FROM students ORDER BY 成绩 DESC,班级) WHERE ROWNUM<=3 ,说实话挺坑的,我一开始也以为ROWNUM是行号,后来发现不对,它其实是当前行的编号。

另外一点,MySQL用LIMIT就行,SELECT 学生姓名,班级,成绩 FROM students ORDER BY 成绩 DESC,班级 LIMIT 0,3 ,这个点很多人没注意,MySQL的LIMIT是从0开始计数的,不是从1 还有个细节挺关键的,比如两个学生成绩并列第一,用ORDER BY怎么处理?比如用RANK() OVER (PARTITION BY 班级 ORDER BY 成绩 DESC)这种写法,但得看数据库支持不,SQL Server 2 01 2 以后支持,Oracle也支持,MySQL早期版本得用窗口函数。

我一开始也以为写个ORDER BY就能搞定所有情况,后来发现不对,还得考虑数据量大的优化问题,比如给成绩和班级字段加索引。
等等,还有个事,如果班级人数特别少,比如只有1 个学生,那这个学生成绩就是第一,用TOP 3 查出来还是他,有没有必要过滤一下?
建议多跑跑实际数据,看看不同数据库的执行计划,别光看写法。