17

クエリに頭を悩ませようとしていますが、理解できません。誰かが私にポインターをくれたら幸いです。私が達成しようとしていることの簡単な例として、私はデータベースにこれらのレコードを持っています

Score|Ranking
-------------
100  |0
200  |0
300  |0

そして、ランキングフィールドに、誰が最高のスコアを獲得したかに基づいて1,2,3を含めるようにしたいので、結果は次のようになります。

Score|Ranking
-------------
100  |3
200  |2
300  |1

現時点では、これらすべてのレコードに対してfor nextループを実行していますが、実際には数千になる可能性があることを考えると、これには永遠にかかる可能性があります。誰かがこれを一度に行う魔法のクエリについてのアイデアを持っていますか?

4

6 に答える 6

25

これを行う方法は次のとおりです。

SET @r=0;
UPDATE table SET Ranking= @r:= (@r+1) ORDER BY Score DESC;

/* use this if you just want to pull it from the db, but don't update anything */
SET @r=0;
SELECT *, @r:= (@r+1) as Ranking FROM table ORDER BY Score DESC;
于 2010-07-07T17:12:35.893 に答える
6

MySQLでは、row_numberを使用できます。

これは:でそれを使用する例SELECTです:

select @rownum:=@rownum+1 ‘rank’, p.* 
from player p, (SELECT @rownum:=0) r 
order by score desc;

このようなものをINSERT INTO使用するSELECTと、ランキングが表示されます。

于 2010-07-07T16:53:35.840 に答える
5

これにより、変数によって増分するプレーヤーをランク付けするインライン更新ステートメントが作成されます@rc。私はこれを非常によく似たケースで何度も使用しましたが、うまく機能し、すべてをDB側に保持します。

SET @rc = 0;
UPDATE players JOIN (SELECT @rc := @rc + 1 AS rank, id FROM players ORDER BY rank DESC)
AS order USING(id) SET players.rank = order.rank;

idテーブルの主キーであると見なされますplayers

于 2010-07-07T17:03:53.817 に答える
2
SET @r = 0;
UPDATE players JOIN (SELECT @r := @r + 1 AS rank, id FROM players ORDER BY rank DESC)
AS sorted USING(id) SET players.rank = sorted.rank;
于 2013-01-04T07:28:53.490 に答える
2

MySQL 8を使用している場合は、新しい関数RANK()を使用できますか

SELECT
    score,
    RANK() OVER (
       ORDER BY score DESC
    ) ranking
FROM
    table;

ランキングを均等に表示したい場合は、DENSE_RANK()もチェックしてください。

そして更新として:

WITH
   ranking AS(
   SELECT
      score,
      RANK() OVER (
         ORDER BY score DESC
      ) ranking
    FROM
        table
)
UPDATE
    table,
    ranking r
SET
    table.ranking = r.ranking
WHERE
    table.score = r.score
于 2020-12-15T12:33:43.417 に答える
1

私はそれを行う私の方法をあなたに示しています[間隔SQL更新関数のために]

選択する:

set @currentRank = 0,
    @lastRating = null,
    @rowNumber = 1;
select
    *,
    @currentRank := if(@lastRating = `score`, @currentRank, @rowNumber) `rank`,
    @rowNumber := @rowNumber + if(@lastRating = `score`, 0, 1) `rowNumber`,
    @lastRating := `score`
from `table`
order by `score` desc

アップデート:

set @currentRank = 0,
    @lastRating = null,
    @rowNumber = 1;
update 
    `table` r
    inner join (
        select
            `primaryID`,
            @currentRank := if(@lastRating = `score`, @currentRank, @rowNumber) `rank`,
            @rowNumber := @rowNumber + if(@lastRating = `score`, 0, 1) `rowNumber`,
            @lastRating := `score`
        from `table`
        order by `score` desc
    ) var on
        var.`primaryID` = r.`primaryID`
set
    r.`rank` = var.`rank`

私はそれが機能することをテストすることを除いて、これでパフォーマンスチェックをしませんでした

于 2012-11-07T13:17:23.570 に答える