
查询每门课程分数最高的学生以及成绩
select aname,acourse,ascore from
test1 a
join (select course,max(score) score from test1 group by course) b
on acourse=bcourse and ascore=bscore;
+--------+--------+-------+
| name | course | score |
+--------+--------+-------+
| 王五 | 语文 | 93 |
| 王五 | 数学 | 99 |
| 张三 | 英语 | 90 |
+--------+--------+-------+
rows in set (000 sec)
需要准备的工具:电脑,sql数据库。
1、首先新建一个test表,有id,name,second三个字段,其中name字段有重复数据。
2、输入“select name,max(second) from test group by name”语句,点击运行。
3、可以看到已经查询出按name分组后取出的second最大的一条记录。
4、以输入“select name,max(second) from test group by name order by max(second) desc”语句,按分组后second最大值进行降序。
5、如果想查询mysql分组后最小的一条记录,输入“select name,min(second) from test group by name”语句,点击运行即可。
前两天同事有个 MySQL 数据分组的需求,如下测试数据,需要找出每个 name 分组中 create_date 最近的记录:
需要注意的是,此处用的 MySQL 是56,最初是使用这条语句:
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 055) 0px 2px 10px;"> select name, value, create_date, update_date from t1 group by name order by create_date desc; </pre>
用这条 SQL 得到的其实只是每个 name 分组中最先插入的记录,然后按照 create_date 进行了降序排列,和原始需求,完全不同。
此时可采用分而治之的策略,先做排序,再做分组:
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 055) 0px 2px 10px;"> select from (select name, value, create_date, update_date from t1 order by create_date desc) t group by tname; </pre>
当然,针对此需求,可能有其他方法,有兴趣的朋友,可以尝试写写,共享一下。
可能有细心的朋友会发现个问题,就是上述 SQL 中的 group by ,好像有些奇怪,如果按照常规,select 中的字段需要出现在 group by 中,上述语句竟然没报错?
如果我们在 MySQL 57 执行相同的语句:
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 055) 0px 2px 10px;"> select name, value, create_date, update_date from t1 group by name order by create_date desc; </pre>
因此从56升级到57,很可能出现这种相同的 SQL 执行结果不同的现象,这对兼容性测试的要求就会很高,究其原因,一方面是特性决定的,另一方面就是各种配置参数不同导致的。
可以在57的 sql_mode 中删除这个 ONLY_FULL_GROUP_BY ,即可达到56相同效果了,或者改写 SQL ,例如:
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 055) 0px 2px 10px;"> select from t1 a where create_date = (select max(create_date) from t1 b where aname = bname); </pre>
或者,
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 055) 0px 2px 10px;"> select from t1 a where not exists (select from t1 b where aname = bname and bcreate_date > acreate_date); </pre>
MySQL 80支持 row_number()函数, *** 作应该和如下 Oracle 相近的。
Oracle 中可以使用 row_number()实现此需求:
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 055) 0px 2px 10px;"> select from (select name, create_date, row_number() over (partition by name order by create_date desc) as r from t1) where r=1; </pre>
以上就是关于MySQL获取分组后的TOP 1全部的内容,包括:MySQL获取分组后的TOP 1、mysql 分组之后如何统计记录条数, gourp by 之后的 count、技术分享 | MySQL 分组需求探秘等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)