sql显示基于mysql计算列的分区

时间:2013-10-06 17:26:25

标签: mysql sql ranking

让我们假装我们有这种关系:

╔═══════════════════╗
║ 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

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:1)

目前还不完全清楚你想要什么,但创造性地使用极限可能会有所帮助:

Set @i = 0;

Select
  (@i := @i + 1) + 2 place,
  s.*
From
  quiz_score s
Order By
  quality Desc
Limit 
  2, 5;

<强> Example Fiddle

答案 1 :(得分:1)

我有适合您的解决方案。重点是在WHERE子句中增加变量。

以下代码显示7行:“Jan”,“Jan”本身以及3之后的3行。

SET @i=0;

SELECT @n:=id, @s:=points FROM Score c WHERE c.username='Jan' ORDER BY points DESC;
SELECT (@i:=@i+1) FROM Score c WHERE c.id <> @n AND c.points <= @s;
SELECT (@i:=@i+1) FROM Dual;

SET @k=0;

SELECT s.* FROM Score s WHERE (@k:=@k+1) >= @i-3 AND @k<= @i+3  ORDER BY points DESC;

SQL Fiddle

如果需要澄清,请告诉我。

答案 2 :(得分:1)

如果您不需要输出中的排名(并且它显示在您的评论和您不喜欢的答案中),您可以简单地将测验分数与Jan的分数结合起来:

查询(SQL Fiddle here):

-- 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;

(请注意,我将结果限制在Jan之前的两个记录和Jan之后的两个记录,因为您的样本数据集非常小。)

需要上述组成查询的括号以允许LIMIT and UNION to work together。最外面的查询然后让我们ORDER the results of a UNION