MySQL 分组取最新的一条记录

 
1. 通过子查询方式实现( 该方法不可取
 
1.1  先将数据按照日期倒序排序(日期最新的在最前面),然后在group,这样每个分类的第一条肯定是日期最新的。
SELECT *
FROM (SELECT *
      FROM test
      WHERE created_time BETWEEN '2018-09-11 00:00:00' AND '2018-09-11 23:59:59'
      ORDER BY `created_time` DESC) `tmp`
GROUP BY category
ORDER BY `created_time` DESC
 
#有问题。这里分组取的并不是每个分组中的第一行数据。
#官方文档说明:去掉sql_mode中的 ONLY_FULL_GROUP_BY
 mysql可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是不确定的,这可能不是您想要的。 此外,通过添加ORDER BY子句不能影响从每个组中选择值。 选择值之后,将进行结果集排序,并且ORDER BY不会影响服务器在每个组中选择哪个值。
 
 
 
1.2   对于自增id来说: 一般id越大的时间越近,可以先选出各个分类最大的id,然后in。
SELECT * 
FROM test 
WHERE id IN (SELECT MAX(id) FROM test GROUP BY category_id);
 
1.3   连表查询,选择出每个分类的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  
 
注:1.2 和 1.3 方法最可靠
 

2. 通过group_concat函数

* 利用 group_concat函数的排序功能
group_concat( [DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator ‘分隔符’] )
 
作用:将要连接的字段按照排序字段的顺序用分隔符连起来显示,默认分隔符是”,”。
如:select group_concat(id order bydatedesc) fromtestgroup by category_id
按照时间排序将id连接起来,第一个一定是时间最新的
 
* 利用substring_index函数来截取第一个值
substring_index(str,delim,count),str:要处理的字符串、delim:分隔符、count:计数
 
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;
 
遇到问题:当每个分租的行数比较多,GROUP_CONCAT()的字段又比较长,会报如下错误:
错误代码: 1105
bytes.Buffer: truncation out of range
原因:group_concat有长度限制
解决方法:变量:group_concat_max_len为1024,设置的大一点
例如:SET SESSION group_concat_max_len=9999999
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值