mysql选择前n个最大值

Posted

技术标签:

【中文标题】mysql选择前n个最大值【英文标题】:mysql select top n max values 【发布时间】:2011-08-28 17:00:34 【问题描述】:

如何从表中选择前 n 个最大值?

对于这样的表:

column1  column2
   1       foo
   2       foo
   3       foo
   4       foo
   5       bar
   6       bar
   7       bar
   8       bar

对于 n=2,结果需要是:

3    
4    
7    
8    

下面的方法只选择每个组的最大值。

SELECT max(column1) FROM table GROUP BY column2

返回:

4
8

【问题讨论】:

您需要 n=2 的解还是任意 n 的一般解? 我实际上更新了解决方案 - 如果您想进一步解释它的工作原理(并且您无法从文章中解决),请告诉我。 @Unreason,非常感谢您的解决方案,效果很好,解释很清楚 所有学分都应该转到 Quassnoi 的精彩博客,如果您要针对相当大的数据集运行查询,您应该阅读有关性能的详细信息(mysql 有时需要一些帮助,这就是其中一种情况) . 【参考方案1】:

对于 n=2 你可以

SELECT max(column1) m 
FROM table t
GROUP BY column2
UNION
SELECT max(column1) m
FROM table t
WHERE column1 NOT IN (SELECT max(column1) 
                      WHERE column2 = t.column2)

对于任何 n,您都可以使用 here 描述的方法来模拟分区上的排名。

编辑: 其实this 文章会给你你所需要的。

基本上是这样的

SELECT t.*
FROM
   (SELECT grouper,
          (SELECT val 
           FROM table li
           WHERE li.grouper = dlo.grouper
           ORDER BY
                 li.grouper, li.val DESC
           LIMIT 2,1) AS mid
   FROM 
      (
      SELECT DISTINCT grouper
      FROM table
      ) dlo 
   ) lo, table t
WHERE t.grouper = lo.grouper
      AND t.val > lo.mid

grouper 替换为您要分组的列的名称,将val 替换为包含值的列的名称。

从最内部的查询开始逐步确定它的功能并运行它们。

此外,还有一点简化 - 如果某个类别没有足够的值,则找到 mid 的子查询可以返回 NULL,因此应该将它的 COALESCE 与一些在比较中有意义的常数(在您的如果它是 val 域的 MIN,在文章中它是 MAX)。

EDIT2: 我忘了说是 LIMIT 2,1 决定了 n (LIMIT n,1)。

【讨论】:

这个答案可以挽救生命。【参考方案2】:

如果您使用的是 mySQl,为什么不使用 LIMIT 功能? 按降序对记录进行排序并限制顶部 n 即:

SELECT yourColumnName FROM yourTableName 
ORDER BY Id desc 
LIMIT 0,3 

【讨论】:

好点,这带来了问题。如果我只想检索最大值,但可能不止一个呢?我尝试过类似 select max(x) where max(x) = (select --top values--) 但不知道如何让它工作。【参考方案3】:

MySQL 8.0/MariaDB 开始支持window functions 专为此类操作而设计:

SELECT *
FROM (SELECT *,ROW_NUMBER() OVER(PARTITION BY column2 ORDER BY column1 DESC) AS r
FROM tab) s
WHERE r <= 2
ORDER BY column2 DESC, r DESC;

DB-Fiddle.com Demo

【讨论】:

【参考方案4】:

这就是我在 MySQL 中获取每组最多 N 行的方式

SELECT co.id, co.person, co.country
FROM person co
WHERE (
SELECT COUNT(*)
FROM person ci
WHERE  co.country = ci.country AND co.id < ci.id
) < 1
;

它是如何工作的:

自加入表 组由co.country = ci.country完成 每组 N 个元素由 ) &lt; 1 控制,因此对于 3 个元素 - ) 获取最大值或最小值取决于:co.id &lt; ci.id co.id co.id > ci.id - min

此处为完整示例:

mysql select n max values per group/

mysql select max and return multiple values

注意:请记住,应该在两个地方都设置其他约束,例如性别 = 0。因此,如果您只想获得男性,那么您应该对内部和外部选择应用约束

【讨论】:

以上是关于mysql选择前n个最大值的主要内容,如果未能解决你的问题,请参考以下文章

ndarray每行N个最大值

从10亿个数据中,取出前1000个最大的数

在 MySQL 中,如何找到分组在特定列上的 N 个最大值的总和? [复制]

mysql中多个字段中的最大值

如何从 sqlite 表中选择文本中的多个最大值

代码随想录算法训练营第13天 | ● 239. 滑动窗口最大值 ● 347.前 K 个高频元素 ● 总结