猿问

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


我有这个文件表(这里是简化版):


+------+-------+--------------------------------------+

| id   | rev   | content                              |

+------+-------+--------------------------------------+

| 1    | 1     | ...                                  |

| 2    | 1     | ...                                  |

| 1    | 2     | ...                                  |

| 1    | 3     | ...                                  |

+------+-------+--------------------------------------+

如何为每个id选择一行并且只选择最大转速?

使用上面的数据,结果应该包含两行:[1, 3, ...]和[2, 1, ..]。我正在使用MySQL。


目前,我在while循环中使用检查来检测并覆盖结果集中的旧转速。但这是实现结果的唯一方法吗?是不是有SQL解决方案?


慕少森
浏览 793回答 4
4回答

牧羊人nacy

乍一看...您只需要一个GROUP BY具有MAX聚合函数的子句:SELECT&nbsp;id,&nbsp;MAX(rev)FROM&nbsp;YourTableGROUP&nbsp;BY&nbsp;id从来没有这么简单,是吗?我刚刚注意到你也需要这个content专栏。这是SQL中一个非常常见的问题:在每个组标识符的列中查找具有一些最大值的行的整个数据。在我的职业生涯中,我听到了很多。实际上,这是我在当前工作的技术面试中回答的问题之一。实际上,StackOverflow社区创建一个标记只是为了处理这样的问题:每个组中最大的n。基本上,您有两种方法可以解决该问题:加入简单的group-identifier, max-value-in-group子查询在这种方法中,您首先group-identifier, max-value-in-group在子查询中找到(上面已经解决过)。然后将表连接到子查询,group-identifier并且两者都相等max-value-in-group:SELECT&nbsp;a.id,&nbsp;a.rev,&nbsp;a.contentsFROM&nbsp;YourTable&nbsp;aINNER&nbsp;JOIN&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;SELECT&nbsp;id,&nbsp;MAX(rev)&nbsp;rev&nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;YourTable&nbsp;&nbsp;&nbsp;&nbsp;GROUP&nbsp;BY&nbsp;id)&nbsp;b&nbsp;ON&nbsp;a.id&nbsp;=&nbsp;b.id&nbsp;AND&nbsp;a.rev&nbsp;=&nbsp;b.revLeft加入self,调整连接条件和过滤器在这种方法中,你自己加入了表。当然,平等在于group-identifier。然后,2个聪明的举动:第二个连接条件是左侧值小于右侧值当你执行第1步时,实际具有最大值的行将NULL在右侧(它是a&nbsp;LEFT JOIN,记住吗?)。然后,我们过滤连接结果,仅显示右侧所在的行NULL。所以你最终得到:SELECT&nbsp;a.*FROM&nbsp;YourTable&nbsp;aLEFT&nbsp;OUTER&nbsp;JOIN&nbsp;YourTable&nbsp;b&nbsp;&nbsp;&nbsp;&nbsp;ON&nbsp;a.id&nbsp;=&nbsp;b.id&nbsp;AND&nbsp;a.rev&nbsp;<&nbsp;b.revWHERE&nbsp;b.id&nbsp;IS&nbsp;NULL;结论两种方法都带来了完全相同的结果。如果有两行max-value-in-groupfor&nbsp;group-identifier,则两行都将在结果中。这两种方法都是SQL ANSI兼容的,因此,无论其“风味”如何,它都可以与您喜欢的RDBMS一起使用。这两种方法都具有性能友好性,但您的里程可能会有所不同(RDBMS,DB结构,索引等)。所以,当你选择一种方法而不是另一种方法时,基准。并确保你选择对你最有意义的一个。

拉丁的传说

我的偏好是使用尽可能少的代码......你可以IN 尝试这样做:SELECT *&nbsp;FROM t1 WHERE (id,rev) IN&nbsp;( SELECT id, MAX(rev)&nbsp; FROM t1&nbsp; GROUP BY id)在我看来它不那么复杂......更容易阅读和维护。

慕的地10843

我很惊讶,没有答案提供SQL窗口功能解决方案:SELECT&nbsp;a.id,&nbsp;a.rev,&nbsp;a.contents&nbsp;&nbsp;FROM&nbsp;(SELECT&nbsp;id,&nbsp;rev,&nbsp;contents, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ROW_NUMBER()&nbsp;OVER&nbsp;(PARTITION&nbsp;BY&nbsp;id&nbsp;ORDER&nbsp;BY&nbsp;rev&nbsp;DESC)&nbsp;rank&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;YourTable)&nbsp;a&nbsp;WHERE&nbsp;a.rank&nbsp;=&nbsp;1在SQL标准ANSI / ISO标准SQL:2003中添加,后来使用ANSI / ISO标准SQL:2008进行了扩展,现在所有主要供应商都可以使用窗口(或窗口)功能。有更多类型的排名函数可用于处理平局问题:RANK, DENSE_RANK, PERSENT_RANK。
随时随地看视频慕课网APP

相关分类

MySQL
我要回答