SQL仅选择列上具有最大值的行[重复]

想改进此帖子吗?提供此问题的详细答案,包括引文和解释您的答案正确的原因。没有足够详细信息的答案可能会被编辑或删除。
这个问题在这里已经有答案了
检索每个组中的最后一条记录-MySQL

(31个答案)

两年前关闭的

我有此文件表(此处为简化版):

id 修订版 内容
一, 一,
二, 一,
一, 二,
一, 三,

如何为每个id选择一行且仅选择最大版本?
对于上述数据,结果应该包含两行:[1,3,…][2,1,…]。我使用的是MySQL

目前我在while循环中使用检查来检测和重写resultset中的旧rev。但是这是实现结果的唯一方法吗?难道没有SQL解决方案吗

乍一看

您只需要一个带有MAXaggregate函数的groupby子句:

选择id,最大值(修订版)
从你的桌子上
按id分组

事情从来没有这么简单,是吗

我刚刚注意到您还需要内容

在SQL中,这是一个非常常见的问题:在某个组标识符的某个列中查找行的全部数据,并使用某个最大值。在我的职业生涯中,我经常听到这个问题。实际上,这是我在当前工作的技术面试中回答的问题之一

事实上,StackOverflow社区创建了一个标签来处理这样的问题是非常普遍的:每个组最多n个标签

基本上,您有两种方法来解决该问题:

与简单的组标识符联接,组中的最大值子查询

在这种方法中,您首先在子查询中找到组标识符,组中的最大值(已在上面解决)。然后将表与子查询连接,并在组标识符组中的最大值上相等:

选择a.id、a.rev、a.contents
从你的桌子上
内连接(
选择id,最大(版本)版本
从你的桌子上
按id分组
)a.id=b.id和a.rev=b.rev上的b

左与自连接,调整连接条件和过滤器

在这种方法中,您将表与自身左键联接。组标识符中的等式为。然后,两个智能移动:

  1. 第二个联接条件是左侧值小于右侧值
  2. 执行步骤1时,实际具有最大值的行的右侧将具有NULL(这是左连接,记得吗?)。然后,我们过滤连接结果,仅显示右侧为NULL的行

因此,你最终会:

选择一个*
从你的桌子上
左表b
在a.id=b.id和a.rev<b.rev上
其中b.id为空;

结论

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

如果对于组标识符,组中有两行的最大值,则两种方法的结果中都有这两行

这两种方法都与SQL ANSI兼容,因此,无论其“风格”如何,都可以与您喜爱的RDBMS一起使用

这两种方法都是性能友好的,但是您的里程数可能会有所不同(RDBMS、DB结构、索引等)。因此,当您选择一种方法而不是另一种方法时,基准测试。并确保选择对您最有意义的方法

发表评论