相关文章推荐
想出家的煎鸡蛋  ·  RFC3164 - BSD ...·  6 月前    · 
沉着的饼干  ·  Traefik重定向·  8 月前    · 
MySQL 排序分组获取最新一条记录

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天, 点击查看活动详情

获取 MySQL 表中修改最新的一条记录,在没有修改时间的时候获取添加时间最新的一条记录,将需求简化后如下图:

通过 SQL 得到红框的 id 为3、4的记录!

SELECT t.* FROM (
    SELECT * FROM t_user ORDER BY create_time DESC, modify_time DESC
) AS t
GROUP BY t.username;

MySQL 版本为 5.6.16 下,执行正常,可以得到红框结果。 但是在 5.7.248.0.15 均报错:

1 queries executed, 0 success, 1 errors, 0 warnings
查询:select t.* from ( select * from t_user order by create_time desc ,modify_time DESC ) as t group by t.username LIMIT 0, 1000
错误代码: 1055
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 't.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
执行耗时   : 0 sec
传送时间   : 0 sec
总耗时     : 0 sec

提示是sql_mode的缘故; 错误原因:在MySQL5.7之后,sql_mode中默认存在ONLY_FULL_GROUP_BY,SQL语句未通过ONLY_FULL_GROUP_BY语义检查所以报错-------引用自MySQL-[Err] 1055 - Expression #1 ONLY_FULL_GROUP_BY:ONLY_FULL_GROUP_BY要求select语句中查询出来的列必须是明确的(其他语句也是一样)。

1、查询 sql_mode;

SELECT @@sql_mode;

2、复制查询的结果,删除ONLY_FULL_GROUP_BY后,重新赋值:

SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
按照原语句查询,虽然不报错,但是得到的是 id为1,4,并不是我们想要的

添加 LIMIT 10000

SELECT t.* FROM (
    SELECT * FROM t_user ORDER BY create_time DESC ,modify_time DESC 
    LIMIT 10000
) AS t
GROUP BY t.username;
加 limit 的非官方解释:
子查询的排序被mysql优化掉了,因为外部查询需要分组,mysql认为子查询排序是没有意义的,但是加了limit子查询排序就有意义----引自mysql 先排序分组 取组里面最新一条数据

分类:
后端