SQL分组取最值

        我们写SQL时,经常会遇到这个逻辑,按某个字段分组然后从每组按某个字段取出最大的一条纪录,我们在oracle、mysql分别探讨一下实现的方法,现在我们开始吧。

新建一张表 exam_results

type results class
数学 23 一班
英语 56 一班
语文 12 一班
数学 8 二班
数学 78 三班
语文 90 二班


oracle

想得到的数据是     按照   type  分组   然后取出每组中  results  最大的那几条纪录。结果应该是这三条纪录:

type results class
数学 78 三班
英语 56 一班
语文 90 二班

方法一: 直接使用聚合函数

SELECT  a.type, MAX(a.results)  FROM  exam_results  a  GROUP BY  a.type

查出来的结果如下:

type results
数学 78
英语 56
语文 90

         这种比较简单,但是有个问题,查询结果不能展示出来class字段(其实也不能不可以,就是比较麻烦,需要修改数据库配置文件或者是用关联的手法写,均不建议),因为ONLY_FULL_GROUP_BY是MySQL数据库提供的一个sql_mode, 通过这个 sql_mode 来保证, SQL语句 “分组求最值” 合法性的检查. 这种模式采用了与 Oracle、DB2 等数据库的处理方式。即不允许 select target list 中出现语义不明确的列。对于用到 GROUP BY 的 select 语句, 查出来的列必须是 group by 后面声明的列, 或者是聚合函数里面的列有这样一个数据库的表。为了解决该问题,又找到了方法二。

方法二:使用ROW_NUMBER() OVER()函数

具体写法如下:

SELECT
	* 
FROM
	( 
        SELECT a.*, row_number ( ) over ( PARTITION BY listid(按此分组) ORDER BY recid(按此排序) DESC ) rn FROM mo_partprg a 
    ) t1 
WHERE
	rn = 1;

套用到我们的表结构中就是

SELECT
	* 
FROM
	( SELECT a.*, row_number ( ) over ( PARTITION BY type ORDER BY results DESC ) rn FROM exam_results a ) t1 
WHERE
	rn = 1;

 查出来的结果如下:

type results class
数学 78 三班
英语 56 一班
语文 90 二班

mysql

经过验证,mysql中如下

Mysql版本5.7可用oracle中方法二

Mysql版本8可用oracle中 方法一、方法二

 欢迎各位大神批评指正,或者提出一些其他的更好的方法大家一起交流学习!

#@lehao#

帮助到您请点赞关注收藏谢谢!!

猜你喜欢

转载自blog.csdn.net/qq_18432653/article/details/125333247