有一个表消息,其中包含如下所示的数据:
Id Name Other_Columns
-------------------------
1 A A_data_1
2 A A_data_2
3 A A_data_3
4 B B_data_1
5 B B_data_2
6 C C_data_1
如果我按名称从消息组中运行查询select *,我将得到如下结果:
1 A A_data_1
4 B B_data_1
6 C C_data_1
哪个查询将返回以下结果?
3 A A_data_3
5 B B_data_2
6 C C_data_1
也就是说,应该返回每个组中的最后一条记录。
目前,这是我使用的查询:
SELECT
*
FROM (SELECT
*
FROM messages
ORDER BY id DESC) AS x
GROUP BY name
但这看起来效率很低。还有其他方法可以达到同样的效果吗?
下面是另一种获取最后一条相关记录的方法,使用GROUP_CONCAT和SUBSTRING_INDEX从列表中选择一条记录
SELECT
`Id`,
`Name`,
SUBSTRING_INDEX(
GROUP_CONCAT(
`Other_Columns`
ORDER BY `Id` DESC
SEPARATOR '||'
),
'||',
1
) Other_Columns
FROM
messages
GROUP BY `Name`
上面的查询将组所有Other_Columns在同一名称组和使用ORDER BY id DESC将连接所有Other_Columns在一个特定的组降序与提供的分隔符在我的情况下,我已经使用||,使用SUBSTRING_INDEX在这个列表将选择第一个
小提琴演示
我们将了解如何使用MySQL获取Group By记录中的最后一条记录。例如,如果你有这个帖子的结果集。
id |
category_id |
post_title |
1 |
1 |
Title 1 |
2 |
1 |
Title 2 |
3 |
1 |
Title 3 |
4 |
2 |
Title 4 |
5 |
2 |
Title 5 |
6 |
3 |
Title 6 |
我想能够得到最后的职位在每个类别是标题3,标题5和标题6。要按类别获取文章,您将使用MySQL Group by键盘。
select * from posts group by category_id
但是我们从这个查询中得到的结果是。
id |
category_id |
post_title |
1 |
1 |
Title 1 |
4 |
2 |
Title 4 |
6 |
3 |
Title 6 |
组by将始终返回结果集中该组中的第一个记录。
SELECT id, category_id, post_title
FROM posts
WHERE id IN (
SELECT MAX(id)
FROM posts
GROUP BY category_id );
这将返回每个组中id最高的帖子。
id |
category_id |
post_title |
3 |
1 |
Title 3 |
5 |
2 |
Title 5 |
6 |
3 |
Title 6 |
参考资料
使用子查询返回正确的分组,因为您已经完成了一半。
试试这个:
select
a.*
from
messages a
inner join
(select name, max(id) as maxid from messages group by name) as b on
a.id = b.maxid
如果它不是id,你想要的最大值:
select
a.*
from
messages a
inner join
(select name, max(other_col) as other_col
from messages group by name) as b on
a.name = b.name
and a.other_col = b.other_col
通过这种方式,可以避免在子查询中进行相关子查询和/或排序,这往往非常缓慢/低效。