问题描述

使用关键字 group by,和order by,但是直接在查询语句后跟上group和order会失效
举例说明:table表中的每个code最新的一条数据
失效写法:

   SELECT t.`value`,t.create_time ,t.codeFROM (SELECT a.code,a.`value`,a.create_timeFROM `table` aORDER BY a.create_time DESC) tGROUP BY t.code;

失效原因:

在mysql5.7手册的8.2.2.1中解释:
子查询的优化是使用半连接的策略完成的(The optimizer uses semi-join strategies to improve subquery execution)
使用半连接进行优化,子查询语句必须满足一些标准(In MySQL, a subquery must satisfy these criteria to be handled as a semi-join)。
其中一个标准是:必须不是一个包含了limit和order by的语句(It must not have ORDER BY with LIMIT.)

生效写法

成功写法一:添加limit

由上述文档解释得到,同时拥有limit和order by的子查询是不会忽略排序的,所以添加limit可以成功分组查询最新
但是有弊端:limit的n写多少合适?如果该需求是个分页列表,如何实现?因此不是最优解

   SELECT t.`value`,t.create_time ,t.codeFROM (SELECT a.code,a.`value`,a.create_timeFROM `table` aORDER BY a.create_time DESC LIMIT #{n}) tGROUP BY t.code;

成功写法二:通过子查询中包含group by语句

我们知道仅仅拥有order by的子查询会被放到外层排序,因此可不可以直接进行分组并排序,不过问题是:mysql的执行顺序order by语句是在group by之后执行的,这个怎么解决?
解决思路:首先分组排序功能在表中的体现一定是两个字段,分组字段(例如用户id,菜单code)和排序字段(创建时间,更新时间)。想一下:子查询中先对排序字段、分组字段进行分组,后跟上order by ,最外层再次根据分组字段分组。分组时字段谁先谁后无影响。
那这不是无效分组了?其实不然,这样做是为了将子查询的排序生效,这个时候添加order by语句,可以试试,是不是成功的在子查询里进行排序了?

   SELECT t.`value`,t.create_time ,t.codeFROM (SELECT a.code,a.`value`,a.create_timeFROM `table` aGROUP BY a.create_time ,a.codeORDER BY a.create_time ) tGROUP BY t.code;

成功写法三: 通过子查询中包含聚合函数

在子查询中使用聚合函数,可以消除合并查询的优化。

   SELECT t.`value`,t.create_time ,t.codeFROM (SELECT a.code,DISTINCT(a.id),a.`value`,a.create_timeFROM `table` aORDER BY a.create_time ) tGROUP BY t.code;

order by 生效的原理

方法二、三中order by 生效的原理:临时表命名后定义为派生表(derived table),Mysql的查询优化器会自动优化sql,并且把派生表合并到外层查询中。

并不是所有带有派生表的查询都能被成功的和外层查询合并,当派生表中有这些语句就不能够和外层查询合并

  • 含有聚集函数,比如MAX()、MIN()、SUM()之类的
  • 使用DISTINCT去重关键字 使用GROUP BY分组关键字
  • 使用HAVING关键字
  • 使用LIMIT关键字
  • 使用UNION 或者 UNION ALL关键字
  • 派生表对应的子查询的SELECT子句中含有另一个子查询

针对order by mysql5.7的文档特殊提到了: 官方文档:8.2.2.4 ,不满足以下三个条件时,派生表会优化order by语句。

The optimizer handles derived tables and view references the same way: It avoids unnecessary materialization whenever possible, which enables pushing down conditions from the outer query to derived tables and produces more efficient execution plans. (For an example, see Section 8.2.2.2, “Optimizing Subqueries with Materialization”.)If merging would result in an outer query block that references more than 61 base tables, the optimizer chooses materialization instead.The optimizer propagates an clause in a derived table or view reference to the outer query block if these conditions are all true: ORDER BY
优化程序传播子句 在派生表或视图中对外部查询块的引用 如果这些条件都为真:ORDER BY1. The outer query is not grouped or aggregated.
外部查询不会分组或聚合。2. The outer query does not specify , , or . DISTINCT HAVIN GORDER BY
外部查询未指定关键字DISTINCT HAVING ORDER BY3. The outer query has this derived table or view reference as the only source in the clause. FROM
外部查询具有此派生表或视图引用 作为子句中的唯一来源。FROMOtherwise, the optimizer ignores the clause. ORDER BY
否则,优化程序将忽略该子句。ORDER BY

MySQL分组查询最新的一条记录相关推荐

  1. mysql 分组取最新的一条记录(整条记录)

    方法:mysql取分组后最新的一条记录,下面两种方法.一种是先筛选 出最大和最新的时间,在连表查询.一种是先排序,然后在次分组查询(默认第一条),就是最新的一条数据了 #select * from t ...

  2. Mysql 分组查询取max 那条记录其他字段

    需求描述: 现有有需求要按类型分组,查询出每一分组最近的一条记录,返回字段包含id,定时任务执行时间(start_time)和任务id(job_id). SELECT id, MAX(start_ti ...

  3. 分组查询最新的一条记录

    SELECT* FROMtable WHEREid IN (SELECTSUBSTRING_INDEX(GROUP_CONCAT(idORDER BYrecord_date DESC,id DESC) ...

  4. mysql分组查询只获取第一条

    mysql分组查询只获取第一条 接到一个需求: 需要获取协议表里所有供应商对应最新的采购员. 由于协议表里供应商的协议会有多个,可能采购员也不是同一个,所以需要做到聚合.筛选才能达到效果. -- 外层 ...

  5. mysql 分组查询最新

    mysql分组查询最新 看到网上说到的方法和我写的都一样,也不知道有没有更好的方法,等到解答. SELECT id,group_id from (SELECT id,group_id from tab ...

  6. mysql查询最新的一条记录_mysql 查询不同用户 最新的一条记录

    数据库记录: MYSQL查询不同用户 最新的一条记录 方法1:查询出结果后将时间排序后取第一条(只能取到一条,并且不能查询不同客户的记录) SELECT CUSTOMER_ID,CONTENT,MOD ...

  7. MYSQL学习:GROUP BY分组取最新的一条记录

    日常开发当中,经常会遇到查询分组数据中最新的一条记录,比如统计当前系统每个人的最新登录记录.外卖系统统计所有买家最新的一次订单记录.图书管理系统借阅者最新借阅书籍的记录等等.今天给大家介绍一下如何实现 ...

  8. mysql分组查询最新数据

    分组查询最新数据是开发中经常遇见的应用场景. 在mysql5.7之前,可以通过 SELECT * FROM ( SELECT * FROM student ORDER BY create_time D ...

  9. [MySQL] 分组排序取前N条记录以及生成自动数字序列,类似group by后 limit

    前言:         同事的业务场景是,按照cid.author分组,再按照id倒叙,取出前2条记录出来.         oracle里面可以通过row_number() OVER (PARTIT ...

最新文章

  1. CoBigICP:一种基于相关熵以及双向匹配的鲁棒且准确的配准方法
  2. 再见 Jenkins!几行脚本搞定自动化部署,这款神器有点厉害
  3. JSTL-EL表达式
  4. 当子元素用position:relative;时,父元素的overflow:hidden;在ie中失效的解决办法
  5. 一个运营专员该如何做好数据分析?
  6. guns使用注意问题
  7. 关于18183-王者荣耀专区网站的TDK简要分析(更多内容请访问http://www.eduaskx6.com/)...
  8. 经典机器学习系列(七)【聚类分析】
  9. JavaSE基础———StringBuffer StringBuilder Arrays和基本数据类型包装类
  10. 手机wps取消不等宽分栏_wps文字怎么取消分栏很简单,三个步骤即可取消
  11. Teraterm 脚本
  12. 超全整理:程序员都在用什么工具?
  13. 新浪邮箱下载的都是php,为什么我用新浪邮箱以及手机号码注册的支付宝能够登陆,但是用163邮箱的支付宝登陆数据库就会报错...
  14. 我所理解的CPU中断
  15. maya表情blendshape_带BlendShape表情的动作文件播放异常
  16. vb.net 教程 20-3 控制Ie浏览器 2 获得Ie窗口的结构
  17. mysql和pg数据库表备份及还原
  18. 数据分析系列 之3σ规则/依据拉依达准则来剔除异常值
  19. Python traceback模块:获取异常信息
  20. 今天goCom财政赤字了

热门文章

  1. GoLang之标准库net/http包源码
  2. 【BZOJ3503】【Cqoi2014】和谐矩阵 高斯消元,解异或方程组
  3. 华为证书HCIE怎么样?考华为HCIE有用吗?
  4. GEE:LST地表温度反演函数(针对Landsat8的T1影像和T1_L2影像集合)
  5. ElasticSearch 全文搜索引擎
  6. 面向医疗数据的差分隐私保护
  7. 青少年CTF-弱口令实验室招新赛部分wp复现步骤
  8. 北斗导航 | 北斗/GNSS精密定位:从PPP-RTK 到 Vision-PPP(第十一届中国卫星导航年会报告)
  9. java 消除png 锯齿_反转(移除)抗锯齿滤波器
  10. 每日一言:站在高山之巅的人