2012-12-23 43 views
3

有其存储在每个玩家的最高分表:打印排名

select * from TMP_TABLE 

导致:

USERID  SCORE 
---------- ----------- 
aaa   10 
bbb   30 
ccc   50 
ddd   90 
eee   80 
fff   50 
ggg   20 
hhh   40 
iii   50 

(9 row(s) affected) 

好了,现在我想每个玩家的节目排名:

select *,r=rank() over(order by score desc) from TMP_TABLE 

导致

USERID  SCORE  r 
---------- ----------- -------------------- 
ddd  90   1 
eee  80   2 
fff  50   3 
ccc  50   3 
iii  50   3 
hhh  40   6 
bbb  30   7 
ggg  20   8 
aaa  10   9 

(9 row(s) affected) 

现在我想打印的用户“BBB”等级和他(她)邻近运动员的姓名和分数,如:

USERID  SCORE  r 
---------- ----------- -------------------- 
hhh  40   6 
bbb  30   7 
ggg  20   8 
(3 row(s) affected) 

不过,我想不出哪个查询语句显示了这一结果。当然,应该考虑处理性能。 请帮帮我。谢谢。

+1

什么'RDBMS'您使用

演示与DENSE_RANK? –

+0

MS SQL Server 2012。 –

回答

3

如果您RDBMS支持Common Table Expression,这是我第一次尝试,

WITH ranking AS 
(
    SELECT *, 
     RANK() OVER (ORDER BY score DESC) userRank 
    FROM TableName 
) 
SELECT * 
FROM ranking 
WHERE userRank BETWEEN 
     (SELECT userRank - 1 FROM ranking WHERE userID = 'bbb') AND 
     (SELECT userRank + 1 FROM ranking WHERE userID = 'bbb') 
1

;WITH cte AS 
(
    SELECT *, 
     RANK() OVER(ORDER BY score DESC) AS r, 
     CASE WHEN USERID = 'bbb' THEN RANK() OVER(ORDER BY score DESC) - 1 END AS bRank, 
     CASE WHEN USERID = 'bbb' THEN RANK() OVER(ORDER BY score DESC) + 1 END AS eRank 
    FROM dbo.TMP_TABLE 
) 
    SELECT USERID, SCORE, r 
    FROM cte c 
    WHERE USERID = 'bbb' OR EXISTS (SELECT 1 FROM cte WHERE c.r BETWEEN bRank AND eRank) 

演示上还有一个选项SQLFiddle

将有可能使用最好的方式DENSE_RANK时HHH和bbb等于上SQLFiddle