常见查询场景

增加排名字段

比如,用户表中,按照年龄排序后,增加rank字段:

# 建表
CREATE TABLE user (id int, name varchar(20), age int, gender char(1));
# 测试数据
INSERT INTO user VALUES (1, 'Bob', 25, 'M');
INSERT INTO user VALUES (2, 'Jane', 20, 'F');
INSERT INTO user VALUES (3, 'Jack', 30, 'M');
INSERT INTO user VALUES (4, 'Bill', 32, 'M');
INSERT INTO user VALUES (5, 'Nick', 22, 'M');
INSERT INTO user VALUES (6, 'Kathy', 18, 'F');
INSERT INTO user VALUES (7, 'Steve', 36, 'M');
INSERT INTO user VALUES (8, 'Anne', 25, 'F');

查询语句:

SELECT    name,
          age,
          gender,
          @curRank := @curRank + 1 AS rank
FROM      user, (SELECT @curRank := 0) r
ORDER BY  age;

查询结果:

分组后取组内TOP 1或者Top N

假如,有成绩表,现在,需要按照课程进行分组,然后取出每门课程成绩最高或Top N 的学生和分数:

TOP 1

方案1:自连接

查询语句如下:

查询结果:

方案2:子查询

查询结果:

TOP N

假设取TOP 2,即取每门课程成绩较高的2个分数和对应的用户。

方案1:使用UNION ALL

如果结果集比较小,可以用程序查询单个分组结果后拼凑,也可以使用UNION ALL拼凑。

查询语句:如果课程共有5中,则写5条单独查,再使用UNION ALL聚合。

查询结果:(共10条记录)

这种方案有一个问题:同一课程,前2高的分数,可能会对应2个以上用户,即可能会漏数据。

方案2:自身左连接

查询语句:

查询结果:

方案3:子查询

查询语句:

查询结果:

方案4 :使用用户变量

查询语句:

查询结果:

这种方案同样有一个问题:同一课程,前2高的分数,可能会对应2个以上用户,即可能会漏数据。

参考

Rank function in MySQL

MySQL获取分组后的TOP 1和TOP N记录

Last updated