sql - 我如何找到每年的前 N ​​名击球手?

标签 sql mysql ranking rank analytic-functions

我正在玩弄 Lahman Baseball Database在 MySQL 实例中。我想找出每年全垒打 (HR) 最高的球员。击球表具有以下(相关部分)的架构:

+-----------+----------------------+------+-----+---------+-------+
| Field     | Type                 | Null | Key | Default | Extra |
+-----------+----------------------+------+-----+---------+-------+
| playerID  | varchar(9)           | NO   | PRI |         |       |
| yearID    | smallint(4) unsigned | NO   | PRI | 0       |       |
| HR        | smallint(3) unsigned | YES  |     | NULL    |       |
+-----------+----------------------+------+-----+---------+-------+

对于每一年,每个玩家都有一个条目(每年数百到 12k 之间,可以追溯到 1871 年)。获得一年的前 N ​​名击球手很容易:

SELECT playerID,yearID,HR
FROM Batting
WHERE yearID=2009
ORDER BY HR DESC LIMIT 3;
+-----------+--------+------+
| playerID  | yearID | HR   |
+-----------+--------+------+
| pujolal01 |   2009 |   47 |
| fieldpr01 |   2009 |   46 |
| howarry01 |   2009 |   45 |
+-----------+--------+------+

但我有兴趣从每年 中找出前 3 名。我找到了类似 this 的解决方案,描述了如何从一个类别中选择顶部,我试图将它应用到我的问题中,结果却得到了一个永远不会返回的查询:

SELECT
    b.yearID, b.playerID, b.HR
FROM
    Batting AS b
LEFT JOIN
    Batting b2
    ON
    (b.yearID=b2.yearID AND b.HR <= b2.HR)
GROUP BY b.yearID HAVING COUNT(*) <= 3;

我哪里做错了?

最佳答案

像这样的东西应该工作:

SELECT b.playerID, b.yearID, b.HR
FROM Batting b 
WHERE HR >= (
    SELECT b2.HR 
    FROM Batting b2 
    WHERE b2.yearID=b1.yearID
    ORDER BY b2.HR DESC
    LIMIT 2, 1
)
ORDER BY b.yearID DESC, b.HR DESC;

解释:选择所有 >= 本垒打数的行作为当年第三高的行。这不会破坏联系。因此,如果有多个击球手的本垒打数相同,他们都会出现。

结果是从最近一年开始排序,并按每年的排名进行子排序。

注意:LIMIT 是从 0 开始的偏移量,所以 2、1 表示从第二行开始后抓取一行,即:第三行。

关于sql - 我如何找到每年的前 N ​​名击球手?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3063716/

相关文章:

mysql - MySQL查询剥离

r - 添加一列排名

r - 基于变量中前 N 个最频繁值的子集数据框

php - 显示该国家世界排名前 5% 和 10% 的奖杯 [按百分比排名系统]

sql - 在远程机器上调用 sqlcmd

mysql - 使用命名子查询 DELETE FROM

sql - 我如何以编程方式找到这些重复记录?

php - MultyQuery 在 phpmyadmin 中工作,在 Mysqli 中不工作,在其他服务器上工作

mysql - 在将某些内容插入到外键引用的子表之前查找主键的值

php - mysql 查询 php