今天面试被sql绊倒了,废话少说,希望以后面试时不再填坑。需求基本和标题一样。
表table1
DROP TABLE IF EXISTS `table1`;
CREATE TABLE `table1` (
`num` int(11) NULL DEFAULT NULL,
`course` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`score` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of table1
-- ----------------------------
INSERT INTO `table1` VALUES (1, '语文', '70');
INSERT INTO `table1` VALUES (1, '数学', '80');
INSERT INTO `table1` VALUES (1, '英语', '90');
INSERT INTO `table1` VALUES (2, '语文', '80');
INSERT INTO `table1` VALUES (2, '数学', '80');
INSERT INTO `table1` VALUES (2, '英语', '77');
INSERT INTO `table1` VALUES (3, '语文', '78');
INSERT INTO `table1` VALUES (3, '数学 ', '93');
INSERT INTO `table1` VALUES (3, '英语', '91');
INSERT INTO `table1` VALUES (4, '语文', '75');
INSERT INTO `table1` VALUES (4, '数学', '89');
INSERT INTO `table1` VALUES (4, '英语', '76');
SET FOREIGN_KEY_CHECKS = 1;
首先 根据学生 num 分组 查询出来 平均成绩
select t1.num, round(avg(t1.score)) as avg_score
from table1 t1
GROUP BY t1.num
ORDER BY avg(t1.score) desc
添加额外的列 并排名 平均分相同的并列同一名
SELECT t.*,
@rows:=@rows+1 as rows,
if(@gnum=avg_score,@rownum:=@rownum,@rownum:=@rownum+1) as rank,
@gnum:=avg_score
FROM (
select t1.num, round(avg(t1.score)) as avg_score
from table1 t1
GROUP BY t1.num
ORDER BY avg(t1.score) desc
)t ,(select @rownum:=0,@gnum:=0,@rows:=0) number
结果如下
此时运用到了sql变量以及赋值
sql变量用@来表示,赋值用:=来实现;
解析一下 首先开始时候 @gnum表示上个总成绩变量 初始化=0, 然后判断是否和上个avg_score相同 相同的话,把上个排名@rownnum赋值给当前列排名,不同则@rownum+1