我有两张桌子players
and scores
.
我想生成一个如下所示的报告:
player first score points
foo 2010-05-20 19
bar 2010-04-15 29
baz 2010-02-04 13
现在,我的查询看起来像这样:
select p.name player,
min(s.date) first_score,
s.points points
from players p
join scores s on s.player_id = p.id
group by p.name, s.points
我需要s.points
与该行关联的min(s.date)
返回。这个查询会发生这种情况吗?也就是说,我如何确定我得到的是正确的s.points
连接行的值?
旁注:我想这在某种程度上与 MySQL 缺乏密集的排名有关。这里最好的解决方法是什么?
这是 Stack Overflow 上经常出现的最大的每组问题。
这是我通常的回答:
select
p.name player,
s.date first_score,
s.points points
from players p
join scores s
on s.player_id = p.id
left outer join scores s2
on s2.player_id = p.id
and s2.date < s.date
where
s2.player_id is null
;
换句话说,给定分数 s,尝试找到同一玩家但日期更早的分数 s2。如果没有找到更早的分数,则 s 是最早的分数。
回复您对领带的评论:您必须制定一项政策,以便在出现领带时使用哪种政策。一种可能性是,如果您使用自动递增主键,则值最小的主键就是较早的主键。请参阅下面的外连接中的附加术语:
select
p.name player,
s.date first_score,
s.points points
from players p
join scores s
on s.player_id = p.id
left outer join scores s2
on s2.player_id = p.id
and (s2.date < s.date or s2.date = s.date and s2.id < s.id)
where
s2.player_id is null
;
基本上,您需要添加决胜局术语,直到您找到一个保证唯一的列,至少对于给定的玩家而言。表的主键通常是最好的解决方案,但我也见过其他列更合适的情况。
关于我与@OMG Ponies 分享的评论,请记住,这种类型的查询从正确的索引中受益匪浅。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)