有时会碰到一些需求,查询分组后的最大值,最小值所在的整行记录或者分组后的top n行的记录,在一些别的数据库可能有窗口函数可以方面的查出来,但是MySQL没有这些函数,没有直接的方法可以查出来,可通过以下的方法来查询。

准备工作

测试表结构如下:

root:test> show create table test1\G

*************************** 1. row ***************************

Table: test1

Create Table: CREATE TABLE `test1` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(20) DEFAULT NULL,

`course` varchar(20) DEFAULT NULL,

`score` int(11) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

插入数据:

insert into test1(name,course,score)

values

('张三','语文',80),

('李四','语文',90),

('王五','语文',93),

('张三','数学',77),

('李四','数学',68),

('王五','数学',99),

('张三','英语',90),

('李四','英语',50),

('王五','英语',89);

查看结果:

root:test> select * from test1;

+----+--------+--------+-------+

| id | name   | course | score |

+----+--------+--------+-------+

| 1 | 张三 | 语文 | 80 |

| 2 | 李四 | 语文 | 90 |

| 3 | 王五 | 语文 | 93 |

| 4 | 张三 | 数学 | 77 |

| 5 | 李四 | 数学 | 68 |

| 6 | 王五 | 数学 | 99 |

| 7 | 张三 | 英语 | 90 |

| 8 | 李四 | 英语 | 50 |

| 9 | 王五 | 英语 | 89 |

+----+--------+--------+-------+

TOP 1

查询每门课程分数最高的学生以及成绩

1、使用自连接【推荐】

root:test> select a.name,a.course,a.score from

-> test1 a

-> join (select course,max(score) score from test1 group by course) b

-> on a.course=b.course and a.score=b.score;

+--------+--------+-------+

| name   | course | score |

+--------+--------+-------+

| 王五 | 语文 | 93 |

| 王五 | 数学 | 99 |

| 张三 | 英语 | 90 |

+--------+--------+-------+

3 rows in set (0.00 sec)

2、使用相关子查询

root:test> select name,course,score from test1 a

-> where score=(select max(score) from test1 where a.course=test1.course);

+--------+--------+-------+

| name   | course | score |

+--------+--------+-------+

| 王五 | 语文 | 93 |

| 王五 | 数学 | 99 |

| 张三 | 英语 | 90 |

+--------+--------+-------+

3 rows in set (0.00 sec)

或者

root:test> select name,course,score from test1 a

-> where not exists(select 1 from test1 where a.course=test1.course and a.score < test1.score);

+--------+--------+-------+

| name   | course | score |

+--------+--------+-------+

| 王五 | 语文 | 93 |

| 王五 | 数学 | 99 |

| 张三 | 英语 | 90 |

+--------+--------+-------+

3 rows in set (0.00 sec)

TOP N

N>=1

查询每门课程前两名的学生以及成绩

1、使用union all

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

root:test> (select name,course,score from test1 where course='语文' order by score desc limit 2)

-> union all

-> (select name,course,score from test1 where course='数学' order by score desc limit 2)

-> union all

-> (select name,course,score from test1 where course='英语' order by score desc limit 2);

+--------+--------+-------+

| name   | course | score |

+--------+--------+-------+

| 王五 | 语文 | 93 |

| 李四 | 语文 | 90 |

| 王五 | 数学 | 99 |

| 张三 | 数学 | 77 |

| 张三 | 英语 | 90 |

| 王五 | 英语 | 89 |

+--------+--------+-------+

6 rows in set (0.01 sec)

2、自身左连接

root:test> select a.name,a.course,a.score

-> from test1 a left join test1 b on a.course=b.course and a.score<b.score

-> group by a.name,a.course,a.score

-> having count(b.id)<2

-> order by a.course,a.score desc;

+--------+--------+-------+

| name   | course | score |

+--------+--------+-------+

| 王五 | 数学 | 99 |

| 张三 | 数学 | 77 |

| 张三 | 英语 | 90 |

| 王五 | 英语 | 89 |

| 王五 | 语文 | 93 |

| 李四 | 语文 | 90 |

+--------+--------+-------+

6 rows in set (0.00 sec)

3、相关子查询

root:test> select *

-> from test1 a

-> where 2>(select count(*) from test1 where course=a.course and score>a.score)

-> order by a.course,a.score desc;

+----+--------+--------+-------+

| id | name   | course | score |

+----+--------+--------+-------+

| 6 | 王五 | 数学 | 99 |

| 4 | 张三 | 数学 | 77 |

| 7 | 张三 | 英语 | 90 |

| 9 | 王五 | 英语 | 89 |

| 3 | 王五 | 语文 | 93 |

| 2 | 李四 | 语文 | 90 |

+----+--------+--------+-------+

6 rows in set (0.01 sec)

4、使用用户变量

root:test> set @num := 0, @course := '';

Query OK, 0 rows affected (0.00 sec)

root:test>

root:test> select name, course, score

-> from (

-> select name, course, score,

-> @num := if(@course = course, @num + 1, 1) as row_number,

-> @course := course as dummy

-> from test1

-> order by course, score desc

-> ) as x where x.row_number <= 2;

+--------+--------+-------+

| name   | course | score |

+--------+--------+-------+

| 王五 | 数学 | 99 |

| 张三 | 数学 | 77 |

| 张三 | 英语 | 90 |

| 王五 | 英语 | 89 |

| 王五 | 语文 | 93 |

| 李四 | 语文 | 90 |

+--------+--------+-------+

6 rows in set (0.00 sec)

MySQL获取分组后的TOP 1和TOP N记录-转的更多相关文章

  1. SQL获取分组后取某字段最大一条记录(求每个类别中最大的值的列表)

    获取分组后取某字段最大一条记录 方法一:(效率最高) select * from test as a where typeindex = (select max(b.typeindex) from t ...

  2. Mysql相关子查询&&MySQL获取分组后的TOP N记录

    小燕子,哈哈哈哈~~~~~~~~~~ 相关子查询是指引用了外部查询列的子查询,即子查询会对外部查询的每行进行一次计算. 举个例子 root:test> show create table tes ...

  3. 【转】Mysql相关子查询&&MySQL获取分组后的TOP N记录

    https://www.cnblogs.com/Yiran583/p/6743870.html select * from test1 a where 2 > (select count(*) ...

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

    MySQL获取分组后的TOP 1和TOP N记录 有时会碰到一些需求,查询分组后的最大值,最小值所在的整行记录或者分组后的top n行的记录,在一些别的数据库可能有窗口函数可以方面的查出来,但是MyS ...

  5. MySQL 对分组后的同类数据进行拼接字符串

    MySQL 对分组后的同类数据进行拼接字符串 写后台方法时遇到个问题,需要将表内同一订单号的操作记录流水进行简单拼接输出,不想取出来再操作,找了个mysql的方法直接操作 //group_concat ...

  6. MySQL 取分组后每组的最新记录

    修改<常用SQL之日期格式化和查询重复数据>中表test1的创建时间,修改后的测试数据如下: 以姓名分组后提取每组最新创建的记录: SELECT a.* FROM test1 AS a, ...

  7. 记一次有意思的 SQL 实现 → 分组后取每组的第一条记录

    开心一刻 今天,朋友气冲冲的走到我面前 朋友:我不是谈了个女朋友,谈了三个月嘛,昨天我偷看她手机,你猜她给我备注什么 我:备注什么? 朋友:舔狗 2 号! 我一听,气就上来了,说道:走,找她去,这婆娘 ...

  8. Mysql 数据分组取某字段值所有最大的记录行

    需求: 表中同一个uid(用户)拥有多条游戏等级记录,现需要取所有用户最高等级(level)的那一条数据,且时间(time)越早排越前.这是典型的排名表 +------+-------+------- ...

  9. Mysql获取去重后的总数

    如果一张表中某个字段存在重复的值,现在我想去重后获取这个字段值的总数 先看这张表 这张表中的openid有重复值 怎么通过sql语句获取openid的去重总数呢 select count(distin ...

随机推荐

  1. 蓝牙发现服务UUID(service UUID)

    出至<蓝牙标准Core_V4.0>2.5.1 uuid(1576页) 其中 Bluetooth_Base_UUID定义为 00000000-0000-1000-8000-00805F9B3 ...

  2. SNF快速开发平台MVC-各种级联绑定方式,演示样例程序(包含表单和表格控件)

    做了这么多项目,经常会使用到级联.联动的情况. 如:省.市.县.区.一级分类.二级分类.三级分类.仓库.货位. 方式:有表单需要做级联的,还是表格行上需要做级联操作的. 实现:实现方法也有很多种方式. ...

  3. Java多线程并发最佳实践

    使用本地变量 尽量使用本地变量,而不是创建一个类或实例的变量. 使用不可变类 String.Integer等.不可变类可以降低代码中需要的同步数量. 最小化锁的作用域范围:S=1/(1-a+a/n) ...

  4. Android launchMode SingleTask newIntent 的问题

    前置条件 项目中,采用 MainActivity + 3个 fragment 的模式作为主要框架.MainActivity 使用 singleTask 模式启动.Fragment 采用 show/hi ...

  5. 译:6.RabbitMQ Java Client 之 Remote procedure call (RPC,远程过程调用)

    在  译:2. RabbitMQ 之Work Queues (工作队列)  我们学习了如何使用工作队列在多个工作人员之间分配耗时的任务. 但是如果我们需要在远程计算机上运行一个函数并等待结果呢?嗯,这 ...

  6. php框架之odp(一)

    熟悉odp框架的使用已经快一个月了,今天总结一下.odp和yii都是成熟的常用的php框架,因为odp是公司内部开发的,且公司内部用odp的较多,所以我就从odp框架入手.仅仅纪录自己的学习体会 一. ...

  7. hdoj:2040

    #include <iostream> #include <vector> using namespace std; vector<long> yueShu(lon ...

  8. greendao引起的NoClassDefFoundError异常解决

    在使用Android studio导入eclipse工程师报错,因为原工程引用了greendao的第三方工程包 java.lang.NoClassDefFoundError: org.greenrob ...

  9. R语言系列:生成数据

    R语言系列:生成数据 (2014-05-04 17:41:57) 转载▼ 标签: r语言 教育 分类: 生物信息 生成规则数据1.使用“:“,如x=1:10,注意该方法既可以递增也可以递减,如y=10 ...

  10. 程序-代写(qq:928900200)

    CS 310 Programming Assignment 4 Due April 27, 2014 5:00 P.M. About 15 years in the future... The Mar ...