mysql分组后,取每组第⼀条数据
拘留所和看守所的区别环境
MySQL:5.7
Java:1.8
SQL语句的写法:
lect*from(lect distinct(a.id) tid, a.*from template_detail a
plate_id in(3,4)
什么是报告
order by a.id desc) tt
group plate_id;
搞笑信息思路:先进⾏排序,然后再进⾏分组,获取每组的第⼀条。
Q: 为什么要写distinct(a.id)呢?
A:防⽌合并的构造(derived_merge);
什么是derived_merge?
derived_merge指的是⼀种查询优化技术,作⽤就是把派⽣表合并到外部的查询中,提⾼数据检索的效率。这个特性在MySQL5.7版本中被引⼊,可以通过如下SQL语句进⾏查看/开启/关闭等操作。
保证书写给女朋友上⾯虽然听起来感觉很⽜逼的样⼦,但是实际情况是,这个新特性,不怎么受欢迎,容易引起错误。
可以在⼦查询中使⽤以下函数来进⾏关闭这个特性:
可以通过在⼦查询中使⽤任何阻⽌合并的构造来禁⽤合并,尽管这些构造对实现的影响并不明确。防⽌合并的构造对于派⽣表和视图引⽤是相同的:
1.聚合函数(SUM(),MIN(),MAX(),COUNT()等)
2.D ISTINCT
3.GROUP BY
4.HAVING
谦卦详解
5.L IMIT
6.UNION或UNION ALL
7.选择列表中的⼦查询
8.分配给⽤户变量
9.仅引⽤⽂字值(在这种情况下,没有基础表)
⼦查询order by失效的场景
lect*from(lect a.*from template_detail a
plate_id in(3,4)
order by a.id desc) tt弄虚作假
group plate_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))。
加了之后就相当于关闭了该特性,所以也就⽣效了。
参考地址:cad比例尺