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

もう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 に答える