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 个元素由 ) < 1
控制,因此对于 3 个元素 - )
获取最大值或最小值取决于:co.id < 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个最大值的主要内容,如果未能解决你的问题,请参考以下文章