想改进此帖子吗?提供此问题的详细答案,包括引文和解释您的答案正确的原因。没有足够详细信息的答案可能会被编辑或删除。
这个问题在这里已经有答案了:
检索每个组中的最后一条记录-MySQL
(31个答案)
(31个答案)
两年前关闭的
我有此文件表(此处为简化版):
id | 修订版 | 内容 |
---|---|---|
一, | 一, | |
二, | 一, | |
一, | 二, | |
一, | 三, |
如何为每个id选择一行且仅选择最大版本?
对于上述数据,结果应该包含两行:[1,3,…]
和[2,1,…]
。我使用的是MySQL
目前我在while
循环中使用检查来检测和重写resultset中的旧rev。但是这是实现结果的唯一方法吗?难道没有SQL解决方案吗
乍一看
您只需要一个带有MAX
aggregate函数的groupby
子句:
选择id,最大值(修订版)
从你的桌子上
按id分组
事情从来没有这么简单,是吗
我刚刚注意到您还需要内容
列
在SQL中,这是一个非常常见的问题:在某个组标识符的某个列中查找行的全部数据,并使用某个最大值。在我的职业生涯中,我经常听到这个问题。实际上,这是我在当前工作的技术面试中回答的问题之一
事实上,StackOverflow社区创建了一个标签来处理这样的问题是非常普遍的:每个组最多n个标签
基本上,您有两种方法来解决该问题:
与简单的组标识符联接,组中的最大值
子查询
在这种方法中,您首先在子查询中找到组标识符,组中的最大值
(已在上面解决)。然后将表与子查询连接,并在组标识符
和组中的最大值
上相等:
选择a.id、a.rev、a.contents
从你的桌子上
内连接(
选择id,最大(版本)版本
从你的桌子上
按id分组
)a.id=b.id和a.rev=b.rev上的b
左与自连接,调整连接条件和过滤器
在这种方法中,您将表与自身左键联接。组标识符中的等式为。然后,两个智能移动:
- 第二个联接条件是左侧值小于右侧值
- 执行步骤1时,实际具有最大值的行的右侧将具有
NULL
(这是左连接
,记得吗?)。然后,我们过滤连接结果,仅显示右侧为NULL
的行
因此,你最终会:
选择一个*
从你的桌子上
左表b
在a.id=b.id和a.rev<;b.rev上
其中b.id为空;
结论
这两种方法都带来了完全相同的结果
如果对于组标识符
,组中有两行的最大值
,则两种方法的结果中都有这两行
这两种方法都与SQL ANSI兼容,因此,无论其“风格”如何,都可以与您喜爱的RDBMS一起使用
这两种方法都是性能友好的,但是您的里程数可能会有所不同(RDBMS、DB结构、索引等)。因此,当您选择一种方法而不是另一种方法时,基准测试。并确保选择对您最有意义的方法