我有一个文档的表格(这里是简化版):
如何选择每个id的一行,且只选择最大的rev?
根据上述数据,结果应包含两行:[1, 3, ...] 和 [2, 1, ..]。我正在使用MySQL。
[1, 3, ...]
[2, 1, ..]
目前,我在while循环中使用检查来检测并覆盖结果集中的旧rev。但是这是实现结果的唯一方法吗?难道没有SQL的解决方案吗?
while
我更喜欢尽可能少使用代码...
你可以使用IN来实现 试试这个:
IN
SELECT * FROM t1 WHERE (id,rev) IN ( SELECT id, MAX(rev) FROM t1 GROUP BY id )
在我看来,这样更简单...更容易阅读和维护。
你只需要在GROUP BY子句中使用MAX聚合函数:
GROUP BY
MAX
SELECT id, MAX(rev) FROM YourTable GROUP BY id
我刚刚注意到你还需要content列。
content
在SQL中,这是一个非常常见的问题:根据某个分组标识符找到某个列中具有最大值的整行数据。在我的职业生涯中,我听到过很多这样的问题。实际上,在我目前的工作的技术面试中,这是我回答的一个问题。
这个问题实际上非常常见,以至于Stack Overflow社区专门创建了一个标签来处理这类问题:greatest-n-per-group。
基本上,你有两种方法来解决这个问题:
group-identifier, max-value-in-group
在这种方法中,你首先在一个子查询中找到group-identifier, max-value-in-group(已经在上面解决了)。然后,你将你的表与子查询进行连接,使用group-identifier和max-value-in-group进行等值连接:
group-identifier
max-value-in-group
SELECT a.id, a.rev, a.contents FROM YourTable a INNER JOIN ( SELECT id, MAX(rev) rev FROM YourTable GROUP BY id ) b ON a.id = b.id AND a.rev = b.rev
在这种方法中,你将表与自身进行左连接。等值连接放在group-identifier中。然后,有两个巧妙的步骤:
NULL
LEFT JOIN
因此,你最终得到:
SELECT a.* FROM YourTable a LEFT OUTER JOIN YourTable b ON a.id = b.id AND a.rev < b.rev WHERE b.id IS NULL;
这两种方法都会得到完全相同的结果。
如果在group-identifier中有两行具有max-value-in-group,那么这两行在两种方法中都会出现在结果中。
这两种方法都与SQL ANSI兼容,因此无论你喜欢的RDBMS是什么“风味”,都可以使用。
这两种方法在性能上也都很友好,但是你的实际情况可能会有所不同(RDBMS、数据库结构、索引等)。因此,在选择一种方法时,要进行基准测试。确保选择对你来说最有意义的方法。
我更喜欢尽可能少使用代码...
你可以使用
IN
来实现 试试这个:在我看来,这样更简单...更容易阅读和维护。
乍一看...
你只需要在
GROUP BY
子句中使用MAX
聚合函数:事情从来都不会那么简单,对吧?
我刚刚注意到你还需要
content
列。在SQL中,这是一个非常常见的问题:根据某个分组标识符找到某个列中具有最大值的整行数据。在我的职业生涯中,我听到过很多这样的问题。实际上,在我目前的工作的技术面试中,这是我回答的一个问题。
这个问题实际上非常常见,以至于Stack Overflow社区专门创建了一个标签来处理这类问题:greatest-n-per-group。
基本上,你有两种方法来解决这个问题:
使用简单的
group-identifier, max-value-in-group
子查询进行连接在这种方法中,你首先在一个子查询中找到
group-identifier, max-value-in-group
(已经在上面解决了)。然后,你将你的表与子查询进行连接,使用group-identifier
和max-value-in-group
进行等值连接:使用自连接进行左连接,并调整连接条件和过滤条件
在这种方法中,你将表与自身进行左连接。等值连接放在
group-identifier
中。然后,有两个巧妙的步骤:NULL
(记住这是一个LEFT JOIN
)。然后,我们过滤连接的结果,只显示右侧为NULL
的行。因此,你最终得到:
结论
这两种方法都会得到完全相同的结果。
如果在
group-identifier
中有两行具有max-value-in-group
,那么这两行在两种方法中都会出现在结果中。这两种方法都与SQL ANSI兼容,因此无论你喜欢的RDBMS是什么“风味”,都可以使用。
这两种方法在性能上也都很友好,但是你的实际情况可能会有所不同(RDBMS、数据库结构、索引等)。因此,在选择一种方法时,要进行基准测试。确保选择对你来说最有意义的方法。