2011-10-29 20 views
1

ゲームで「ハイスコア」や「トップ10スコア」を更新する手順を実装したいと考えています。LIMITのINに代わる方法はありますか?

私の考えでは、次のコードを実行することです:

DELETE FROM Highscore 
WHERE scoreId NOT IN 
    (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10) 

をしかし、私は私が使用しているのMySQLのバージョンはLIMITINをサポートしていないというエラーが出ます。

別の方法がありますか?

答えて

2

のための別の回避策:

DELETE FROM Highscore 
WHERE scoreId NOT IN 
    (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10) 

は別のサブクエリの内部LIMITでサブクエリを囲むことである。

DELETE FROM Highscore 
WHERE scoreId NOT IN 
    (SELECT scoreId FROM 
     (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10) 
     AS tmp 
    ) 

しかし、私はそれがWHEREで、参照をネストされたサブクエリを結合しないことをお勧めだと思います句を、削除したいテーブルに置き換えます。それはあなたの場合に可能であるとして(以下が維持されることに注意してください、

DELETE h 
FROM 
     Highscore AS h 
    CROSS JOIN 
     (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10 
    ) AS tmp 
WHERE h.scoreId NOT IN (SELECT scoreId FROM tmp) 

またはより良い、あなたはそれを簡単に(そしておそらくより速くvalue上のインデックスを持つ)ことができる場合:私はJOINを使用する方が良いと思います10位以上の場合は10行以上):

DELETE h 
FROM 
     Highscore AS h 
    CROSS JOIN 
     (SELECT value 
     FROM Highscore 
     ORDER BY value DESC 
     LIMIT 1 OFFSET 9 
    ) AS tmp 
WHERE h.value < tmp.value 
+0

mhnmは仕事でなければなりません:)非常にトリッキーな、タンク –

1

新しい行を挿入する代わりに、UPDATEを使用して既存の行を更新できます。

もう1つの方法は、ハイスコアを取得する選択を編集することです。そうすれば、以前のハイスコアをすべて追跡することができます。 ORDER BYLIMITを使用すると、このようなクエリを実行できます。

+0

ruこの質問に答えるつもりはありますか? –

+1

更新? mhnm?スコアが最も低い行?私はそれが良い考えだとは思わない。ゲームが終了すると、すべての人のスコアがデータベースに送信されます(人数は可変です)。だから私はこの場合にUPDATEを使う方法がわからない –

+0

'DELETE'では' LIMIT'を使うことができますが、 'OFFSET'ではできません。 –

0

私はMySQLがこれを上のテストにインストール必要はありませんが、TSQLにあなたはもちろん

delete from HighSchore 
where scoreID not in 
(select top 10 scoreID from HighScore order by Value desc) 

ような何かを行うことができ、それは外側のサブクエリの代わりに参加してこれを行う方が良いでしょう。

また、私の意見では、このようなデータは決して削除してはいけませんが、必要なときには常にトップ10を取得してください。最後5は任意の番号にすることができ

select top 10 value 
from Highscore 
order by Value desc; 
+0

mysqlは内側のクエリ内でトップ/リミットを許可しません。 –

+0

@ItayMoav真剣に?誰もが他のサーバーのためにそれを必要とする場合は、私はここに残しておきます。 –

+2

私たちALL(mysqlユーザー)は、これが間もなく修正されることを願っていますが、残念ながら、これは現在のところ存在していますが、まだ安定していません。 –

3
DELETE FROM Highscore ORDER BY value DESC LIMIT 10,5 

。スコアを追加するたびにこれを実行すると、1とすることができます。エラーのマージンを増やすには、10を使用します。

編集:申し訳ありませんが、ここではオフセットを使用できません。その場合:

DELETE FROM Highscore WHERE value < (SELECT value FROM Highscore ORDER BY value DESC LIMIT 10,1) 

が、それはあなたが(/更新として同じテーブルから選択削除)することをやらせていない場合は、試してみてください。

SET @tmp = (SELECT value FROM Highscore ORDER BY value DESC LIMIT 10,1) 
DELETE FROM Highscore WHERE value < @tmp 

EDIT再び:コメントで指摘したように11番目の値が10の場合に問題が発生します。試してみてください:

SET @id = (SELECT scoreId FROM Highscore ORDER BY value DESC, scoreId DESC LIMIT 10,1), @val = (SELECT value FROM Highscore ORDER BY value DESC LIMIT 10,1) 
DELETE FROM Highscore WHERE value <= @val AND scoreId < @id 

注文scoreIdで最初の変数には同じスコアを持ついくつかがある場合には、何も10未満が残されないことを保証します。

+0

'SET @tmp =(高値ORDER BY値DESC LIMIT 10,1) 高値から削除WHERE値<@ tmp'これは動作しますが、少しバグがあります(11行が10行と同じ値を持つ場合) –

+0

ああ、それは良い点です。より堅牢なクエリで編集します。 –

+0

ああ確かに...ありがとう:) –

0

これを試してください。

まず、NOTトップ10

DELETE FROM Highscore WHERE scoreId NOT IN 
    (SELECT scoreId FROM tmp_highscores) 

そして、忘れないでそれらを削除し、その後、トップ10

CREATE TEMPORARY TABLE tmp_highscores 
    (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10); 

の一時テーブルを作成します。"scoreIdは"「にインデックスを作成する必要があります

関連する問題