mysql选择前n个最大值

时间:2011-05-19 09:01:27

标签: mysql greatest-n-per-group

如何从表格中选择前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

4 个答案:

答案 0 :(得分:4)

对于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)。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

这就是我在MySQL中获得每组N max行的方式

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个元素由) < 1控制,因此对于3个元素 - )&lt; 3
  • 获取最大值或最小值取决于:co.id < ci.id
    • co.id&lt; ci.id - max
    • co.id&gt; ci.id - min

这里有完整的例子:

mysql select n max values per group/

mysql select max and return multiple values

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

应用约束

答案 3 :(得分:0)

从专为此类操作设计的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