MySQL分组方式-限制到第一个X记录
我在网络上做了一个很好的观察,似乎很多人都有类似的问题,但我似乎找不到一个解决我问题的明确方法 为了提供一些背景信息,我正在运行一个体育网站,并拥有一个数据库,其中包含了过去的成绩——跨越数千条记录 下面是一些示例数据-表名:matchesMySQL分组方式-限制到第一个X记录,mysql,group-by,Mysql,Group By,我在网络上做了一个很好的观察,似乎很多人都有类似的问题,但我似乎找不到一个解决我问题的明确方法 为了提供一些背景信息,我正在运行一个体育网站,并拥有一个数据库,其中包含了过去的成绩——跨越数千条记录 下面是一些示例数据-表名:matches | match_id | manager_id | outcome | | -------- | ---------- | ------- | | 1 | 1 | W | | 2 |
| match_id | manager_id | outcome |
| -------- | ---------- | ------- |
| 1 | 1 | W |
| 2 | 1 | D |
| 3 | 1 | D |
| 4 | 2 | L |
| 5 | 2 | L |
| 6 | 2 | W |
| 7 | 2 | D |
| 8 | 2 | L |
| 9 | 2 | L |
| 10 | 3 | W |
| 11 | 3 | W |
| 12 | 3 | W |
| 13 | 3 | W |
| 14 | 3 | D |
| 15 | 3 | D |
| 16 | 4 | L |
| 17 | 4 | L |
| 18 | 4 | D |
| 19 | 5 | W |
| 20 | 5 | W |
我想做的是计算每个经理的匹配数,以及结果——这是我通过使用此查询获得的结果
SELECT
`manager_id`,
COUNT(*) AS `played`,
SUM(`outcome` = 'W') AS `won`,
SUM(`outcome` = 'D') AS `drawn`,
SUM(`outcome` = 'L') AS `lost`,
ROUND((SUM(`outcome` = 'W')/COUNT(*)) * 100, 0) AS `win_percentage`
FROM
`matches`
GROUP BY `manager_id`
查询结果
| manager_id | played | won | drawn | lost | win_percentage |
| ---------- | ------ | --- | ----- | ---- | -------------- |
| 1 | 3 | 1 | 2 | 0 | 33 |
| 2 | 6 | 1 | 1 | 4 | 16 |
| 3 | 6 | 4 | 2 | 0 | 66 |
| 4 | 3 | 0 | 1 | 2 | 0 |
| 5 | 2 | 2 | 0 | 0 | 100 |
这一切都很好,而且做起来相对简单
然而,我想要实现的是根据每个管理者id的前X个记录数找出完全相同的数据
例如,假设我需要每个管理器的前两个匹配项的上述数据。我应该得出如下结果
| manager_id | played | won | drawn | lost | win_percentage |
| ---------- | ------ | --- | ----- | ---- | -------------- |
| 1 | 2 | 1 | 1 | 0 | 50 |
| 2 | 2 | 0 | 0 | 2 | 0 |
| 3 | 2 | 2 | 0 | 0 | 100 |
| 4 | 2 | 0 | 0 | 2 | 0 |
| 5 | 2 | 2 | 0 | 0 | 100 |
以上只是一个例子,因为在现实中,我们将搜索每组的前50或100个匹配项
非常感谢您对我的支持。因为MySql中没有窗口函数,所以您可以使用中描述的变量
你首先如何定义?顺序是什么?按匹配id的顺序,按经理id分组。基本上,每个经理id的前X个匹配id记录数。
set @howmany := 2;
SELECT
manager_id,
COUNT(*) AS played,
SUM(outcome = 'W') AS won,
SUM(outcome = 'D') AS drawn,
SUM(outcome = 'L') AS lost,
ROUND((SUM(outcome = 'W')/COUNT(*)) * 100, 0) AS win_percentage
FROM
(SELECT
match_id,
manager_id,
outcome,
CASE WHEN manager_id != @manager THEN @row := 1
ELSE @row := @row + 1 END as rownum,
CASE WHEN manager_id != @manager THEN @manager := manager_id
ELSE @manager END as _
FROM (SELECT * from matches ORDER BY manager_id, match_id) temp1
JOIN (SELECT @manager := 0) temp2
JOIN (SELECT @row := 0) temp3
) temp
WHERE temp.rownum <= @howmany
GROUP BY manager_id;