我正在玩MySQL实例中的Lahman Baseball Database。我想找到每年超过本垒打(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 | |
+-----------+----------------------+------+-----+---------+-------+
每年,每位玩家都有一个参赛作品(每年数百到12万,可追溯到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;
我哪里出错?
答案 0 :(得分: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;
说明:选择所有具有&gt; =本垒打数的行作为该年度的第三高行。这不会打破关系。因此,如果不止一个击球手拥有相同数量的全垒打,他们都会出现。
结果是从最近一年订购的,按每年的排名顺序排列。
注意:LIMIT是一个基于0的偏移量,因此2,1表示在第二行抓取一行后开始,即:第三行。
答案 1 :(得分:0)
select *
from (
select
b.yearID as year,
b.teamID as team,
m.nameFirst as first,
m.nameLast as last,
find_in_set(b.HR, x.teamRank) as rank,
b.HR as HR
from
Batting b
inner join Master m on m.playerID = b.playerID
inner join (select yearID, group_concat(distinct HR order by HR desc) as teamRank from Batting group by yearID) x on x.yearID = b.yearID
) x
where
rank <= 10 and rank > 0
order by
year desc, rank
或者2010年每支球队的前5名人力资源总数......
select *
from (
select
b.yearID as year,
b.teamID as team,
m.nameFirst as first,
m.nameLast as last,
b.HR as HR,
find_in_set(b.HR, x.teamRank) as rank
from
Batting b
inner join Master m on m.playerID = b.playerID
inner join (select teamID, group_concat(distinct HR order by HR desc) as teamRank from Batting where yearID = 2010 group by teamID) x on x.teamID = b.teamID
where
b.yearID = 2010
) x
where
rank <= 5 and rank > 0
order by
team, rank
limit 12
显示这些结果......
year team first last HR rank
2010 ARI Mark Reynolds 32 1
2010 ARI Chris Young 27 2
2010 ARI Kelly Johnson 26 3
2010 ARI Adam LaRoche 25 4
2010 ARI Justin Upton 17 5
2010 ATL Brian McCann 21 1
2010 ATL Jason Heyward 18 2
2010 ATL Troy Glaus 16 3
2010 ATL Martin Prado 15 4
2010 ATL Eric Hinske 11 5
2010 BAL Luke Scott 27 1
2010 BAL Ty Wigginton 22 2