让我们假设我们有这个关系:
╔═══════════════════╗ ║ i++ name score ║ ╠═══════════════════╣ ║ 1 Will 123 ║ ║ 2 Joe 100 ║ ║ 3 Bill 99 ║ ║ 4 Max 89 ║ ║ 5 Jan 43 ║ ║ 6 Susi 42 ║ ║ 7 Chris 11 ║ ║ 8 Noa 9 ║ ║ 9 Sisi 4 ║ ╚═══════════════════╝
现在我需要一个基于我正在搜索的数据的子集。例如,我正在寻找第五个地方。在我的结果中,我需要的不仅仅是 Jan 的记录,我还需要 Jan 之前的两条记录以及 Jan 后面的两条记录。所以我有以下结果集:
╔═══════════════════╗ ║ id++ name score ║ ╠═══════════════════╣ ║ 3 Bill 99 ║ ║ 4 Max 89 ║ ║ 5 Jan 43 ║ ║ 6 Susi 42 ║ ║ 7 Chris 11 ║ ╚═══════════════════╝
那是我得到的sql:
select @a:= id from quiz.score where username = 'Jan'; set @i=0; SELECT @i:=@i+1 as Platz, s.* FROM quiz.score s where id BETWEEN @a-5 AND @a+5 order by points desc;
这里的问题是,@a是id记录的。有没有办法使用计算值@i:=@i+1?
@a
id
@i:=@i+1
非常感谢您的帮助。
如果您不需要输出中的排名(并且它在您的评论和喜欢的答案中显示出来,而您并不需要),则可以简单地组合最接近Jan得分的测验得分:
查询(此处为SQL Fiddle):
-- XXX this assumes `scores`.`username` is UNIQUE ! SELECT * FROM ( -- Get those who scored worse (or tied) ( SELECT s.* FROM scores s CROSS JOIN (SELECT score FROM scores WHERE username = 'Jan') ref WHERE s.score <= ref.score AND username <> 'Jan' ORDER BY s.score DESC LIMIT 2) UNION -- Get our reference point record (SELECT s.* FROM scores s WHERE username = 'Jan') UNION -- Get those who scored better ( SELECT s.* FROM scores s CROSS JOIN (SELECT score FROM scores WHERE username = 'Jan') ref WHERE s.score > ref.score AND username <> 'Jan' ORDER BY s.score ASC LIMIT 2) ) slice ORDER BY score ASC;
(请注意,由于示例数据集太小,我将结果限制为1月之前的两个记录和1月之后的两个记录。)
为了使LIMIT和UNION可以一起使用,需要在上面的组成查询上加上这些括号。然后,最外面的查询使我们可以对UNION的结果进行ORDER排序。