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)

但是,我无法弄清楚哪个查询语句显示了这个结果。当然,还要考虑处理性能。请帮我。谢谢你。

4

2 回答 2

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')
于 2012-12-23T07:40:31.083 回答
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上的演示

当 hhh 和 bbb 相等时,可以使用最佳方式 DENSE_RANK

SQLFiddle上的 DENSE_RANK 演示

于 2012-12-23T10:30:54.390 回答