登录  /  注册
如何使用SQL检索具有最高值的列中的行 [重复]
P粉211273535
P粉211273535 2023-09-20 13:44:50
[MySQL讨论组]

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

id 内容
1 1 ...
2 1 ...
1 2 ...
1 3 ...

如何选择每个id的一行,且只选择最大的rev?

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

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

P粉211273535
P粉211273535

全部回复(2)
P粉336536706

乍一看...

你只需要在GROUP BY子句中使用MAX聚合函数:

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

使用自连接进行左连接,并调整连接条件和过滤条件

在这种方法中,你将表与自身进行左连接。等值连接放在group-identifier中。然后,有两个巧妙的步骤:

  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、数据库结构、索引等)。因此,在选择一种方法时,要进行基准测试。确保选择对你来说最有意义的方法。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号