问题

我有这个表格的文件(简体版本):

+------+-------+--------------------------------------+
| id   | rev   | content                              |
+------+-------+--------------------------------------+
| 1    | 1     | ...                                  |
| 2    | 1     | ...                                  |
| 1    | 2     | ...                                  |
| 1    | 3     | ...                                  |
+------+-------+--------------------------------------+

如何为每个ID选择一行,而且只有最大的修改? 使用上述数据,结果应该包含两行: [1,3,...] [2,1,..] .我使用的是 MySQL .

目前我在 while 循环中使用检查来检测和覆盖结果集中的旧版本.但是这是实现结果的唯一方法吗?是否有 SQL 解决方案?

更新 如答案所示,一个SQL解决方案,这里是一个sqlfiddle演示.

更新2
我注意到,在添加上述sqlfiddle之后,问题被upvote的速度已经超过了upvote率的答案.这是没有的意图!小提琴基于答案,特别是接受的答案.



解决方法

At first glance...

您所需要的是 GROUP BY 子句与 MAX 聚合函数:

SELECT id, MAX(rev)
FROM YourTable
GROUP BY id

It's never that simple, is it?

我只是注意到您还需要 content 列.

这是SQL中一个非常常见的问题:根据某个组标识符,在列中找到具有某个最大值的整个数据.我在我的职业生涯中听说了很多.其实,这是我在我目前的工作技术面试中回答的问题之一.

实际上,StackOverflow社区已经创建了一个标签来处理这样的问题,这是很常见的:.

基本上,你有两种方法来解决这个问题:

Joining with simple group-identifier, max-value-in-group Sub-query

在此方法中,您首先在子查询中找到 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

Left Joining with self, tweaking join conditions and filters

在这种方法中,你离开连接表与自己.当然,平等在 group-identifier 中.然后,2智能移动:

  1. The second join condition is having left side value less than right value
  2. When you do step 1, the row(s) that actually have the max value will have NULL in the right side (it's a LEFT JOIN, remember?). Then, we filter the joined result, showing only the rows where the right side is NULL.

所以你最后得到:

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;

Conclusion

两种方法都带来完全相同的结果.

如果您对 group-identifier max-value-in-group 的两行,则两行都将出现在两种方法的结果中.

这两种方法都是SQL ANSI兼容的,因此,无论其"风味"如何,都将与您最喜欢的RDBMS配合使用.

这两种方法都是性能友好的,但是您的里程可能不同(RDBMS,DB结构,索引等).因此,当您选择其中一种方法时,基准.并确保你选择对你最有意义的那个.




相关问题推荐