mysql取出每个分组中最新的记录(坑点勿踩)

1.子查询解决方案

先将数据按照日期倒序排序(日期最新的在最前面),然后在group,这样每个分类的第一条肯定是日期最新的。

select * from (select * from `test` order by `date` desc) `temp`  group by category_id order by `date` desc

2.通过group_concat函数

①group_concat函数

group_concat( [DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator ‘分隔符’] )

作用:将要连接的字段按照排序字段的顺序用分隔符连起来显示,默认分隔符是”,”。
如:select group_concat(id order by date desc) from test group by category_id
按照时间排序将id连接起来,第一个一定是时间最新的。

②substring_index

substring_index(str,delim,count),str:要处理的字符串、delim:分隔符、count:计数
例子:
  SELECT SUBSTRING_INDEX(‘www.test.com’,’.’,1);
  结果是:www
  SELECT SUBSTRING_INDEX(‘www.test.com’,’.’,2)
  结果是:www.test
  SELECT SUBSTRING_INDEX(‘www.test.com’,’.’,-2);
  结果为:test.com

也就是说,如果count是正数,那么就是从左往右数,第N个分隔符的左边的全部内容,相反,如果是负数,那么就是从右边开始数,第N个分隔符右边的所有内容。
③解析
GROUP_CONCAT将group by 后的id排序后连接起来,SUBSTRING_INDEX取得每行(每个分类)的第一个。

SELECT * FROM `test` WHERE id IN 
(SELECT SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY `date` DESC),',',1) FROM `test` GROUP BY category_id)
ORDER BY `date` DESC;

3.连表方式(推荐使用)

连表,选择出每个分类的category_id和最大时间作为一个临时表,然后原表和临时表连接,条件是分类id和时间相等。

-- 方法一
SELECT * FROM test AS a, 
(SELECT category_id, MAX(DATE) AS `date` FROM test AS b GROUP BY category_id) AS b 
WHERE a.category_id=b.category_id AND a.date = b.date  
-- 方法二
SELECT * FROM test AS a WHERE date = (SELECT  MAX(date) FROM test AS b WHERE a.category_id=b.category_id) 

通常在效率上比方法二高很多,方法二首次运行很慢,内存中包含相应的数据后再次执行速度比较快。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值