mysql - SQL 仅选择列上具有最大值的行

标签 mysql sql aggregate-functions greatest-n-per-group groupwise-maximum

我有这个文档表格(这里是简化版本):

<表类=“s-表”> <标题> id 转 内容 <正文> 1 1 ... 2 1 ... 1 2 ... 1 3 ...

如何为每个 ID 选择一行且仅选择最大的转速?
使用上述数据,结果应包含两行:[1, 3, ...][2, 1, ..] 。我正在使用MySQL

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

最佳答案

乍一看...

您所需要的只是一个带有 MAX 聚合函数的 GROUP BY 子句:

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

事情从来没有那么简单,不是吗?

我刚刚注意到您还需要 content 列。

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

事实上,这种情况非常常见,以至于 Stack Overflow 社区创建了一个标签来处理这样的问题: .

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

使用简单的group-identifier, max-value-in-group子查询连接

在此方法中,您首先在子查询中找到group-identifier, max-value-in-group(上面已解决)。然后,将表连接到子查询,并在 group-identifiermax-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

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

在这种方法中,您将表与其自身左连接。平等存在于group-identifier中。然后,2个聪明的举动:

  1. 第二个连接条件是左侧值小于右侧值
  2. 当您执行第 1 步时,实际具有最大值的行将在右侧显示 NULL(这是一个 LEFT JOIN,还记得吗?) 。然后,我们过滤连接结果,仅显示右侧为 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;

结论

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

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

这两种方法都兼容 SQL ANSI,因此,无论其“风格”如何,都可以与您最喜欢的 RDBMS 配合使用。

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

关于mysql - SQL 仅选择列上具有最大值的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46108781/

相关文章:

mysql - 如何取时间列的平均值并将输出显示为时间

php:使用参数从另一个 php 文件执行 php 文件

mysql - Tomcat/Hibernate 与 MySql 的连接失败,出现 "Communications link failure"和 "Permission denied"

sql - 如何从周中获得一天

MySQL:是否可以通过单个查询来做到这一点?

三节点之间的mysql复制(master主复制和一个定向slave)

mysql - sql outer join 显示 mysql workbench 中的错误

sql - 如何在postgresql中将两行转换为键值json对象?

arrays - Postgres数组比较困惑

mysql - 如何有条件地选择聚合函数返回值?