问题描述:Mysql5.7版本中,查询分组GROUP BY通过子查询中ORDER BY进行排序无效的问题解决办法。
应用场景:一对多的关系,通常需要取最新、最近的一条数据时。
举例:比如客户表,订单表,一个客户可能有很多订单,一对多的关系,我们想查询每个客户最新的一单数据
客户id | 姓名 |
---|---|
1001 | 客户张三 |
1002 | 客户李四 |
订单id | 客户id | 下单时间 |
---|---|---|
1 | 1001 | 2023-11-10 15:20:00 |
2 | 1001 | 2023-11-11 15:10:00 |
3 | 1002 | 2023-09-11 12:20:00 |
4 | 1003 | 2023-10-11 14:20:00 |
5 | 1003 | 2023-12-11 20:20:00 |
6 | 1003 | 2023-12-21 14:20:00 |
常规操作:尝试使用子查询,先排序再分组,取最新一条
SELECT * FROM ( SELECT * FROM `order_info` ORDER BY created_time desc ) AS t GROUP BY customer_id
但是这个方式在低版本中有效,
在 5.7 版本中引入新特性 derived_merge 优化过后,group by子句中使用order by导致order by失效,所以你发现取到的不是最新的!
SELECT * FROM ( SELECT * FROM `order_info` HAVING 1=1 ORDER BY created_time desc ) AS t GROUP BY customer_id
用一个超级大的limit放在order by后面
SELECT * FROM ( SELECT * FROM `order_info` ORDER BY created_time desc LIMIT 1000000 ) AS t GROUP BY customer_id
一些场景,如果是有序递增的,可以通过取Max(id)方式,实现效果
SELECT * FROM order_info where order_id in ( SELECT MAX( order_id ) FROM order_info GROUP BY customer_id )
取到最新的数据在关联客户表查询即可。
上边提到了取最新、最近数据的可试方法,那还有一种常见场景是删除重复的记录(只保留一条)怎么处理呢:SQL删除重复的记录(只保留一条)-窗口函数row_number()