mysql分组后,取每组第一条数据或最新一条

mysql分组后,取每组第一条数据或最新一条环境 MySQL 5 7Java 1 8SQL 语句的写法 select from selectdistin a id tid a fromtemplate detailawhere template idin 3 4 orderbya iddesc ttgroupbytt template id 思路 先进行排序 然后再进行分组 获取每组的第一条 Q 为什么要写 distinct a i

环境

SQL语句的写法:

select * from (select distinct(a.id) tid, a.* from template_detail a where a.template_id in (3, 4) order by a.id desc) tt group by tt.template_id; 

思路:先进行排序,然后再进行分组,获取每组的第一条。

通过子查询中的order by a.id desc就可以做到是每组最新一条,还是第一条。
通过实践,我们知道这种查询方式,与分组子查询相比性能慢了些,慢一点点

-- 这种查询方式更快一丢丢 SELECT bb.`detail`, bb.`id`,bb.`template_id` from `template_detail` bb INNER JOIN ( SELECT MAX(`id`) id, `template_id` from `template_detail` GROUP BY `template_id` ) as tb on bb.`id` = tb.id 

Q: 为什么要写distinct(a.id)呢?
A:防止合并的构造(derived_merge);

什么是derived_merge?

derived_merge指的是一种查询优化技术,作用就是把派生表合并到外部的查询中,提高数据检索的效率。这个特性在MySQL5.7版本中被引入,可以通过如下SQL语句进行查看/开启/关闭等操作。

上面虽然听起来感觉很牛逼的样子,但是实际情况是,这个新特性,不怎么受欢迎,容易引起错误。

可以在子查询中使用以下函数来进行关闭这个特性:

可以通过在子查询中使用任何阻止合并的构造来禁用合并,尽管这些构造对实现的影响并不明确。 防止合并的构造对于派生表和视图引用是相同的: 1.聚合函数( SUM()MIN()MAX()COUNT()等) 2.DISTINCT 3.GROUP BY 4.HAVING 5.LIMIT 6.UNION或UNION ALL 7.选择列表中的子查询 8.分配给用户变量 9.仅引用文字值(在这种情况下,没有基础表) 

子查询order by失效的场景

select * from (select a.* from template_detail a where a.template_id in (3, 4) order by a.id desc) tt group by tt.template_id; 

假设我们现在把distinct(a.id) tid, 去掉,会发现子查询(或者叫:临时表)中的order by a.id desc失效了。
为什么会这样呢?

原理分析:

我们这里使用了临时表排序,继而对其结果进行分组,结果显示失败,加了distinct(a.id) tid, 后结果正确,原因是因为临时表(派生表derived table)中使用order by且使其生效,必须满足三个条件:

  1. 外部查询禁止分组或者聚合
  2. 外部查询未指定having,HAVING, order by
  3. 外部查询将派生表或者视图作为from句中唯一指定源

不满足这三个条件,order by会被忽略。

一旦外部表使用了group by,那么临时表(派生表 derived table)将不会执行filesort操作(即order by 会被忽略),所以我在临时表中加了(distinct(a.id))。
加了之后就相当于关闭了该特性,所以也就生效了。

参考地址:

https://dev.mysql.com/doc/refman/5.7/en/derived-table-optimization.html

分组查询取每组最新的数据(order by 和group by使用问题)

mysql分组后获取每个组排序后的第一条数据(整行)

Mysql取分组后的每组第一条数据

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231755.html原文链接:https://javaforall.net

(0)
上一篇 2025年11月23日 下午8:01
下一篇 2025年11月23日 下午8:22


相关推荐

  • 最新kali之dirbuster

    最新kali之dirbuster描述 目录扫描工具 DirBuster 支持全部的 Web 目录扫描方式 它既支持网页爬虫方式扫描 也支持基于字典暴力扫描 还支持纯暴力扫描 该工具使用 Java 语言编写 提供命令行 Headless 和图形界面 GUI 两种模式 其中 图形界面模式功能更为强大 用户不仅可以指定纯暴力扫描的字符规则 还可以设置以 URL 模糊方式构建网页路径 同时 用户还对网页解析方式进行各种定制 提高网址解析效率 选项 h 显示帮助信息 H 以无头模式 无 GUI 启动 DirBuster 报告将在退出时自动保存

    2025年11月29日
    6
  • 十大开源视频会议「建议收藏」

    十大开源视频会议「建议收藏」视频会议及流媒体十大开源项目 在视频会议领域,有许多可以值得参考的开源项目,这些开源项目有的是协议栈、有的是编码器或者是传输协议,由于视频会议系统是一个综合性的应用系统,里面包含功能较多,如能把这些开源项目选择性的加入我们的视频会议开发当中,我们的开发效率肯定会事半功倍,下面我们列举一下视频会议相关的十大开源项目,并对其重要性及优缺点做一个全面的评价与排名。1、 OpenH323项

    2022年7月12日
    87
  • vs中使用openGL

    vs中使用openGL

    2021年11月19日
    62
  • SkeyePlayer RTSP播放器源码解析系列之H264一帧多NAL写MP4录像花屏问题解决方案

    SkeyePlayer RTSP播放器源码解析系列之H264一帧多NAL写MP4录像花屏问题解决方案接上一篇[SkeyePlayer源码解析系列之录像写MP4]之续篇,我们来讲解一下关于H264编码格式中的一帧多nal(NetworkAbstractLayer,即网络抽象层),关于H264和NAL,这里引用一段话来科普一下:【转】在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。因此我们平时的每帧数据就是一个NAL单元

    2022年10月9日
    3
  • 2019最新Web前端经典面试试题及答案-史上最全前端面试题(含答案)

    2019最新Web前端经典面试试题及答案-史上最全前端面试题(含答案)近期总结一一些面试题都是企业的面试题笔记题感觉薪资10k下的都会出笔试题特别高的薪资都是直接技术面试或者是现场编程总结很多人的面试题,后期会对于单个知识点再说笔记详细讲解。部分都是百度的答案,不是特全面的,可以自己找下同时分享一个自己录制的CSS3动画特效经典案例【推荐教程】–后期会更新vue框架微信小程序等内容。https://ke.qq.com/cou…

    2022年5月31日
    41
  • 如何检查并清除挖矿程序

    如何检查并清除挖矿程序1 检查 cpu 使用率根据 cpu 使用率曲线确定 2 11 日可能被注入挖矿程序 根据 top 确定挖矿程序进程 kdevtmpfsi2 确定挖矿进程源程序位置 find namekdevtmpf 查看安装时间 对比 cpu 突然拔升时间 3 检查 psadm2 用户的合法性 4 检查 root 或者 psadm2 用户下是否有定时挖矿的复制文件任务 crontab lcrontab r 删除定时任务 5 杀死挖矿进程 pkillkdevtmp 删

    2026年3月17日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号