mysql - 在 GROUP BY 中使用 LIMIT 来获得每组 N 个结果?

标签 mysql sql group-by greatest-n-per-group ranking

以下查询:

SELECT
year, id, rate
FROM h
WHERE year BETWEEN 2000 AND 2009
AND id IN (SELECT rid FROM table2)
GROUP BY id, year
ORDER BY id, rate DESC

产量:

year    id  rate
2006    p01 8
2003    p01 7.4
2008    p01 6.8
2001    p01 5.9
2007    p01 5.3
2009    p01 4.4
2002    p01 3.9
2004    p01 3.5
2005    p01 2.1
2000    p01 0.8
2001    p02 12.5
2004    p02 12.4
2002    p02 12.2
2003    p02 10.3
2000    p02 8.7
2006    p02 4.6
2007    p02 3.3

我想要的只是每个 id 的前 5 个结果:

2006    p01 8
2003    p01 7.4
2008    p01 6.8
2001    p01 5.9
2007    p01 5.3
2001    p02 12.5
2004    p02 12.4
2002    p02 12.2
2003    p02 10.3
2000    p02 8.7

有没有办法使用某种在 GROUP BY 中工作的 LIMIT 之类的修饰符来做到这一点?

最佳答案

您想要查找每组前 n 行。这个答案提供了一个使用与OP不同的示例数据的通用解决方案。

在 MySQL 8 或更高版本中,您可以使用 ROW_NUMBER , RANK or DENSE_RANK 函数取决于 top 5 的确切定义。以下是这些函数根据 value 生成的数字降序排序。注意如何处理关系:

<表类=“s-表”> <标题> pkid catid 值 row_number 排名 dense_rank <正文> 1 p01 100 *1 *1 *1 2 p01 90 *2 *2 *2 3 p01 90 *3 *2 *2 4 p01 80 *4 *4 *3 5 p01 80 *5 *4 *3 6 p01 80 6 *4 *3 7 p01 70 7 7 *4 8 p01 60 8 8 *5 9 p01 50 9 9 6 10 p01 40 10 10 7

一旦您选择了该功能,请像这样使用它:

SELECT *
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY value DESC) AS n
    FROM t
) AS x
WHERE n <= 5

DB<>Fiddle

<小时/>

在 MySQL 5.x 中,您可以使用穷人的分区等级来实现所需的结果:将表与其自身进行外连接,并为每一行计算之前的行数 它(例如,前一行可能是具有更高值的行)。

以下命令将产生类似于 RANK 的结果功能:

SELECT t.pkid, t.catid, t.value, COUNT(b.value) + 1 AS rank
FROM t
LEFT JOIN t AS b ON b.catid = t.catid AND b.value > t.value
GROUP BY t.pkid, t.catid, t.value
HAVING COUNT(b.value) + 1 <= 5
ORDER BY t.catid, t.value DESC, t.pkid

进行以下更改以产生类似于 DENSE_RANK 的结果功能:

COUNT(DISTINCT b.value)

或者进行以下更改以产生类似于 ROW_NUMBER 的结果功能:

ON b.catid = t.catid AND (b.value > t.value OR b.value = t.value AND b.pkid < t.pkid)

DB<>Fiddle

关于mysql - 在 GROUP BY 中使用 LIMIT 来获得每组 N 个结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25603414/

相关文章:

python - 中位数为 'modified' 的 Csv pandas groupby

r - 使用 dplyr 对 R 中的组进行索引

mysql搜索查询问题like query

php - 加入表后不从数据库中检索行

mysql - JOIN 或 LEFT JOIN 是否持续检查 SELECT 查询?

sql - 如何在 RLIKE Hive 中转义单引号?双单引号不起作用

mysql - 从 MySQL 选择行并使用 MAX 和 MIN 进行分组

mysql - 在 32 位或 64 位 Linux 操作系统服务器上使用 Nginx+mysql 运行 Ruby on Rails + Phusion Passenger 及其性能?

java "database is locked"SQL异常

mysql - 如何在Mysql中使用MATCH AGAINST而不是LIKE