获取使用group by 分组后的组内最新(最大,最...)的一条数数据

sql取group by 分组后的组内最新(最大,最…)的一条数数据

最近一个有个需求是 , 取分组后的组内最新的一条数据, 正常来说写法如下

select a.* from
	(
	select cluesTaracking_id,cluesId,trackingTime,fail_why from cluestracking
	order by trackingTime desc
	) a
	group by a.cluesId

但是查询结果却是取得id最小的一条数据
不分组查询结果
在这里插入图片描述

分组后的查询结果
在这里插入图片描述

明显可以看出分组后并没有取trackingTime最大的一条数据

解决方案

方法一

在order by后面添加 limit X, 比如这里添加limit 100, sql如下

select a.* from
	(
	select cluesTaracking_id,cluesId,trackingTime,fail_why from cluestracking
	order by trackingTime desc
	limit 100
	) a
	group by a.cluesId

查询结果如下
在这里插入图片描述

可以看到, 已经将分组后组内最新的一条数据查出

问题解析:

通过explain方式, 查看执行逻辑
将limit 100注释掉
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iEEd1000-1608015395467)(en-resource://database/515:0)]

发现这里的select_type是SIMPLE, SIMPLE表示这是一个
简单的SELECT语句(不包括UNION操作或子查询操作),
也就是虽然写了子查询和排序, 但是并未生效, 依然使用的是默认的排序, 即按照id升序排列

打开limit 100的注释

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nm6bjULq-1608015395469)(en-resource://database/517:0)]

PRIMARY
查询中最外层的SELECT(如两表做UNION或者存在子查询的外层的表操作为PRIMARY,内层的操作为UNION)
'DERIVED:
DERIVED表示被驱动的SELECT子查询(子查询位于FROM子句)
由此可见 , 在mysql 5.7中, 如果想要获取分组后的最新数据, 必须加上limit 条数, 这里可以指定一个不可能查询出的数值,如1000等

方法二 使用 MAX() 聚合函数

 select cluesTaracking_id,cluesId,
 MAX(trackingTime),
 fail_why from cluestracking
	group by cluesId
	order by trackingTime desc

查询结果如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ldeDM001-1608015395472)(en-resource://database/519:0)]

方法一的查询结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y7oTkcgm-1608015395475)(en-resource://database/521:0)]

可以看到, 查询结果一致

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
可以通过Mybatis Plus的Lambda QueryWrapper和子查询来实现分组后查询每组最新一条数据的功能。具体实现步骤如下: 1. 构建Lambda QueryWrapper对象,设置分组条件和排序条件: ``` QueryWrapper<Entity> wrapper = new QueryWrapper<>(); wrapper.select("group_id", "max(create_time) as create_time") .groupBy("group_id") .orderByDesc("create_time"); ``` 2. 构建子查询,查询每组最新一条数据的id: ``` QueryWrapper<Entity> subWrapper = new QueryWrapper<>(); subWrapper.select("id") .inSql("concat(group_id, '_', create_time)", "select concat(group_id, '_', max(create_time)) from entity group by group_id"); ``` 3. 根据子查询构建Lambda QueryWrapper对象,查询每组最新一条数据的详细信息: ``` QueryWrapper<Entity> queryWrapper = new QueryWrapper<>(); queryWrapper.in("id", subWrapper); List<Entity> entityList = entityMapper.selectList(queryWrapper); ``` 其中,第1步中的select语句中,group_id为分组字段,create_time为时间字段,max(create_time)表示获取每组中最新一条数据的时间。orderByDesc("create_time")表示按时间倒序排列,确保每组最新一条数据排在最前面。 第2步中的子查询中,concat(group_id, '_', create_time)表示将group_id和create_time拼接成一个字符串,以便后面使用inSql函查询。 第3步中的in函中,将子查询的结果作为参传入,查询每组最新一条数据的详细信息。 这样就可以实现分组后查询每组最新一条数据的功能了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

意田天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值