我正在MySQL实例中使用Lahman Baseball Database。我想找到每年在全垒打(HR)中名列前茅的球员。Batting表具有以下架构(相关部分):
+-----------+----------------------+------+-----+---------+-------+
| 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 |
+-----------+--------+------+
但我对每年的前三名感兴趣。我找到了类似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/