MySQL 分组排序

这篇博客探讨了在MySQL中如何查询分组后的单条和多条记录。对于查询每个班级的最高分,文章指出直接使用MAX函数可能会导致数据不匹配。在MySQL 5.7及更高版本中,可以通过子查询配合LIMIT解决。同时,如果需要查询每个班级的前两名成绩,可以使用子查询或窗口函数来实现。

比如有一个全年级成绩表(grade):

idname(姓名)score(分数)class_id(班级)
1张三681
2李四701
3王五851
4刘六632
5陈七902
........................

一,查询分组后单条记录

比如现要求查询出每个班级成绩最好的:

1,分组后取最大的(错误) 

SELECT *, MAX(score) as maxscore FROM `grade` GROUP BY class_id

这个sql只能查询出每个班级的最高分(class_id,maxscore),其它字段数据完全不是最高分的匹配记录

2,排序后分组(看版本)

--mysq <= 5.6 
SELECT * FROM (SELECT * FROM `grade` ORDER BY score DESC) as f GROUP BY class_id

--mysq > 5.6 
 SELECT * FROM (SELECT * FROM `grade` ORDER BY score DESC LIMIT 10000000 ) as f GROUP BY class_id

5.7之后(包括5.7)对子查询排序做了优化,子查询全表排序失效,但可以在子查询里面加limit,排序能继续生效

3,子查询

SELECT a.* FROM `grade` a WHERE score = (SELECT MAX(score) FROM `grade` WHERE class_id = a.class_id) 

注意:如果一个班级有多个相同的最高分score的话,查出结果单个班级会出多条记录,只要一条的话可以在sql后面加GROUP BY class_id

二,查询分组后多条记录

比如要求查出每个班级成绩最好的两条数据:

1,子查询

SELECT a.* FROM `grade` a WHERE ( 
    SELECT COUNT(*) FROM `grade` WHERE class_id = a.class_id AND a.score < score
) < 2 

2,窗口函数

--mysql >= 8.0
SELECT * FROM (
    SELECT *, ROW_NUMBER() OVER(PARTITION BY class_id ORDER BY score DESC) as rowno FROM `grade`
) f WHERE rowno <=2

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值