前言
需求:MySQL 按照时间排序
,合并取第一条
记录
问题复现
无效示例如下
select newData.member_id,any_value(newData.amount) from (select member_id,amount as amount from user_log ORDER BY create_time desc ) as newData GROUP BY newData.member_id
先进行排序,然后再进行分组,获取每组的第一条。如果使用子查询 order by 会失效
,分组后的数据没有按照预期返回排序的第一条数据。
疑问
:为什么没有按照预期查询出数据?
因为MySQL5.7版本中被引入derived_merge
导致(派生表合并到外部的查询中,提高数据检索的效率)
详细可查看MySQL 官方文档解释,地址为:https://dev.mysql.com/doc/refman/5.7/en/derived-table-optimization.html
解决方案
以下来自于官方文档解决
可以通过在子查询中使用任何阻止合并的构造来禁用合并,尽管它们对实现的影响并不那么明确。防止合并的构造对于派生表和视图引用是相同的:
- 聚合函数(SUM()、 MIN()、 MAX()、 COUNT()等)
- DISTINCT
- GROUP BY
- HAVING
- LIMIT
- UNION或者 UNION ALL
- 选择列表中的子查询
- 分配给用户变量
- 仅引用文字值(在这种情况下,没有基础表)
有效示例如下
select newData.member_id,any_value(newData.amount) from (select distinct(member_id),amount as amount from user_log ORDER BY create_time desc ) as newData GROUP BY newData.member_id
总结
临时表执行排序,后对其结果进行分组,没有达到预期,加了 DISTINCT
、聚合函数
后达到预期,原因是因为临时表(派生表derived table)中使用order by且使其生效,必须满足三个条件:
- 外部查询禁止分组或者聚合
- 外部查询未指定having,HAVING, order by
- 外部查询将派生表或者视图作为from句中唯一指定源
不满足这三个条件,排序会被忽略。详细可查看上文中 解决方案
处理
来源地址:https://blog.csdn.net/weixin_39793790/article/details/130573695