本文共 1726 字,大约阅读时间需要 5 分钟。
在MySQL中,由于缺少窗口函数(如RANK、DENSE_RANK等),某些常见需求需要通过其他方法来实现。以下将详细介绍如何解决以下两种常见需求:
推荐使用自连接的方法,通过将结果集与自身连接,筛选出成绩最高的学生。
select a.name, a.course, a.scorefrom test1 ajoin test1 b on a.course = b.course and a.score = b.scorewhere b.score = (select max(score) from test1 where course = a.course);
通过在主查询中使用相关子查询,直接筛选出成绩最高的记录。
select name, course, scorefrom test1 awhere score = (select max(score) from test1 where a.course = test1.course);
另一种方法是利用NOT EXISTS
子查询,排除低于最高分的记录。
select name, course, scorefrom test1 awhere not exists( select 1 from test1 where a.course = test1.course and a.score < test1.score);
通过将每门课程的前两名成绩合并,使用UNION ALL
操作。
(select name, course, scorefrom test1where course = '语文' order by score desc limit 2)union all (select name, course, scorefrom test1where course = '数学' order by score desc limit 2)union all (select name, course, scorefrom test1where course = '英语' order by score desc limit 2);
通过左连接自身表,筛选出每门课程前两名的学生。
select a.name, a.course, a.scorefrom test1 aleft join test1 b on a.course = b.course and a.score = b.scoregroup by a.name, a.course, a.scorehaving count(b.id) < 2order by a.course, a.score desc;
通过子查询筛选出每门课程前两名的学生。
select *from test1 awhere 2 > (select count(*) from test1 where course = a.course and score > a.score)order by a.course, a.score desc;
通过设置用户变量,逐步筛选出前两名的学生。
set @num := 0, @course := '';select name, course, scorefrom test1where ( @num := if(@course = course, @num + 1, 1) as row_number, @course := course as dummy from test1 order by course, score desc) as xwhere x.row_number <= 2;
这些方法均可在MySQL中实现分组后获取最值及前N名记录的需求,适用于窗口函数缺失的情况。
转载地址:http://todfk.baihongyu.com/