有一个表消息,其中包含如下所示的数据:

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

但这看起来效率很低。还有其他方法可以达到同样的效果吗?


当前回答

你可以通过计数来分组,也可以得到分组的最后一项,比如:

SELECT 
    user,
    COUNT(user) AS count,
    MAX(id) as last
FROM request 
GROUP BY user

其他回答

是什么:

select *, max(id) from messages group by name 

我已经在sqlite上测试了它,它返回所有列和所有名称的最大id值。

这个怎么样:

SELECT DISTINCT ON (name) *
FROM messages
ORDER BY name, id DESC;

我也有类似的问题(在postgresql tough上),在1M的记录表上。这个解决方案需要1.7秒,而使用LEFT JOIN的解决方案需要44秒。 在我的例子中,我必须根据NULL值过滤您的名称字段的对应项,从而使性能更好0.2秒

这是另一个没有子查询的选项。

本解决方案使用MySQL的LAST_VALUE窗口函数,利用窗口函数框架提供MySQL工具。

SELECT DISTINCT 
    LAST_VALUE(Id)            
        OVER(PARTITION BY Name 
             ORDER     BY Id 
             ROWS BETWEEN 0 PRECEDING 
                      AND UNBOUNDED FOLLOWING),
    Name,
    LAST_VALUE(Other_Columns)            
        OVER(PARTITION BY Name 
             ORDER     BY Id 
             ROWS BETWEEN 0 PRECEDING 
                      AND UNBOUNDED FOLLOWING)
FROM   
    tab

在这里试试。

我得到了一个不同的解决方案,这是获得每个组中最后一个帖子的id,然后从消息表中选择使用第一个查询的结果作为WHERE x IN构造的参数:

SELECT id, name, other_columns
FROM messages
WHERE id IN (
    SELECT MAX(id)
    FROM messages
    GROUP BY name
);

我不知道与其他一些解决方案相比,它的性能如何,但对于我有300多万行的表来说,它的效果非常好。(4秒执行,1200+结果)

这应该工作在MySQL和SQL Server。

我们将了解如何使用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

参考资料