有一个表 messages
包含如下数据:
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 * from messages group by name
,我会得到如下结果:
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
但这看起来效率很低。还有其他方法可以达到相同的结果吗?
原文由 Vijay Dev 发布,翻译遵循 CC BY-SA 4.0 许可协议
MySQL 8.0 现在支持 窗口函数,就像几乎所有流行的 SQL 实现一样。使用这个标准语法,我们可以编写每个组的最大 n 个查询:
MySQL 手册中说明了这种和其他查找 分组最大行 的方法。
以下是我在 2009 年为这个问题写的原始答案:
我这样写解决方案:
关于性能,一种或另一种解决方案可能会更好,具体取决于数据的性质。因此,您应该测试这两个查询并使用给定数据库性能更好的查询。
例如,我有一份 StackOverflow August data dump 的副本。我将使用它进行基准测试。
Posts
表中有 1,114,357 行。这是在我的 Macbook Pro 2.40GHz 上的 MySQL 5.0.75 上运行的。我将编写一个查询来查找给定用户 ID(我的)的最新帖子。
首先在子查询中使用@Eric 显示 的技术和
GROUP BY
:即使是
EXPLAIN
分析也 需要 16 秒:现在使用 我的技术 与
LEFT JOIN
产生相同的查询结果:EXPLAIN
分析表明两个表都能够使用它们的索引:这是我的
Posts
表的 DDL:评论者注意:如果您想要另一个具有不同版本的 MySQL、不同的数据集或不同的表设计的基准测试,请随意自己做。我已经展示了上面的技术。 Stack Overflow 在这里向您展示如何进行软件开发工作,而不是为您完成所有工作。