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 的修饰符来做到这一点?

最佳答案

您可以使用 GROUP_CONCAT聚合函数将所有年份放入单个列中,按 id 分组并按 rate 排序:

SELECT   id, GROUP_CONCAT(year ORDER BY rate DESC) grouped_year
FROM     yourtable
GROUP BY id

结果:

-----------------------------------------------------------
|  ID | GROUPED_YEAR                                      |
-----------------------------------------------------------
| p01 | 2006,2003,2008,2001,2007,2009,2002,2004,2005,2000 |
| p02 | 2001,2004,2002,2003,2000,2006,2007                |
-----------------------------------------------------------

然后你可以使用 FIND_IN_SET ,返回第一个参数在第二个参数中的位置,例如。

SELECT FIND_IN_SET('2006', '2006,2003,2008,2001,2007,2009,2002,2004,2005,2000');
1

SELECT FIND_IN_SET('2009', '2006,2003,2008,2001,2007,2009,2002,2004,2005,2000');
6

使用 GROUP_CONCATFIND_IN_SET 的组合,并按 find_in_set 返回的位置进行过滤,然后您可以使用此查询,该查询仅返回每个 id 的前 5 年:

SELECT
  yourtable.*
FROM
  yourtable INNER JOIN (
    SELECT
      id,
      GROUP_CONCAT(year ORDER BY rate DESC) grouped_year
    FROM
      yourtable
    GROUP BY id) group_max
  ON yourtable.id = group_max.id
     AND FIND_IN_SET(year, grouped_year) BETWEEN 1 AND 5
ORDER BY
  yourtable.id, yourtable.year DESC;

请看 fiddle here .

请注意,如果多行可以具有相同的速率,您应该考虑在 rate 列上使用 GROUP_CONCAT(DISTINCT rate ORDER BY rate) 而不是年份列。

GROUP_CONCAT 返回的字符串的最大长度是有限的,所以如果您需要为每个组选择几条记录,这很有效。

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

相关文章:

mysql - MySQL 能否生成可以为负数或正数的随机数?

mysql - 合并依赖于另一个结果集的查询

mysql - 计算与unix时间戳的不同间隔匹配的行数(MYSQL)

mysql - 将 varchar mm/dd/yy 转换为日期格式 yyyy-mm-dd

python - 在 Pandas 分组后绘制多个时间序列

scala - GroupBy 多列作为键并对多列求和,如 sql 吗?

mysql - 从表中删除冗余记录(MySQL)

sql - 如何根据另一列的一部分更新列

mysql - 为什么 "admin' #"work as a sql injection attack on MySql but "admin' - -"doesn' t?

mysql - SQL 内连接分组依据