3

重複の可能性:
GROUP BY 内の SQL ORDER BY 合計

更新:ここに投稿した解決策を見つけました。助けてくれてありがとう!


リーダーボードを必要とする Facebook アプリケーションを開発しています。ゲームを完了するのにかかったスコアと時間が記録され、これらは最初にスコアで整理され、次に2つの同一のスコアの場合は時間が使用されます. ユーザーが複数回プレイした場合、最高のスコアが使用されます。

スコアが低いほど、ゲームのパフォーマンスが向上します。

私のテーブル構造は次のとおりです。

id
facebook_id - (Unique Identifier for the user)
name
email
score
time - (time to complete game in seconds)
timestamp - (unix timestamp of entry)
date - (readable format of timestamp)
ip

私がうまくいくと思ったクエリは次のとおりです。

SELECT *
FROM entries
ORDER BY score ASC, time ASC
GROUP BY facebook_id

私が抱えている問題は、場合によっては、データベース内のユーザーの最高スコアではなく、最初のスコアを取得していることです。これは GROUP BY ステートメントにかかっていると思います。ORDER BY ステートメントでこれが修正されると思っていましたが、明らかにそうではありませんでした。

例えば:

----------------------------------------------------------------------------
|  ID  |       NAME       |  SCORE  |  TIME  |  TIMESTAMP  |  DATE  |  IP  |
----------------------------------------------------------------------------
|  1   |  Joe Bloggs      |  65     |   300  | 1234567890  |  XXX   |  XXX |
----------------------------------------------------------------------------
|  2   |  Jane Doe        |  72     |   280  | 1234567890  |  XXX   |  XXX |
----------------------------------------------------------------------------
|  3   |  Joe Bloggs      |  55     |   285  | 1234567890  |  XXX   |  XXX |
----------------------------------------------------------------------------
|  4   |  Jane Doe        |  78     |   320  | 1234567890  |  XXX   |  XXX |
----------------------------------------------------------------------------

上記のクエリを使用すると、次の結果が得られます。

 1. Joe Bloggs - 65 - 300 - (Joes First Entry, not his best entry) 
 2. Jane Doe - 72 - 280

私は期待していただろう...

 1. Joe Bloggs - 55 - 285 - (Joe's best entry)
 2. Jane Doe - 72 - 280 

Group By が Order を無視しているようで、値を上書きしているだけです。

group by で MIN(score) を使用すると、最も低いスコアが選択されますが、これは正しいですが、データベース内のユーザーの最初のレコードから時間がマージされるため、多くの場合、誤って返されます。

では、ユーザーの最高スコアと関連する時間、名前などを選択し、結果をスコア、次に時間で並べ替えるにはどうすればよいでしょうか?

前もって感謝します!

4

5 に答える 5

3

順序はgroupbyの後にある必要があるため、クエリは実際には意味がありません。どのSQLエンジンを使用していますか?ほとんどの場合、エラーが発生します。

私はあなたが望むものはもっと似ていると思います:

select e.facebookid, minscore, min(e.time) as mintime -- or do you want maxtime?
from entries e join
     (select e.facebookid, min(score) as minscore
      from entries e
      group by facebookid
     ) esum
     on e.facebookid = esum.facebookid and
        e.score = e.minscore
group by e.facebookid, minscore

ウィンドウ関数を使用してこれを行うこともできますが、それはデータベースによって異なります。

于 2012-06-29T14:15:29.313 に答える
2

あなたはスコアを最小化する必要があります

    SELECT
      facebook_id,
      name,
      email,
      min(score) as high_score
    FROM
      entries
    GROUP BY
      facebook_id,
      name,
      email
   ORDER BY
     min(score) ASC
于 2012-06-29T14:16:32.813 に答える
2

1 つのアプローチは次のとおりです。

SELECT entries.facebook_id, MIN(entries.score) AS score, MIN(entries.time) AS time
FROM entries
    INNER JOIN (
        SELECT facebook_id, MIN(score) AS score
        FROM entries
        GROUP BY facebook_id) highscores
    ON highscores.facebook_id = entries.facebook_id
    AND entries.score = highscores.score
GROUP BY entries.facebook_id
ORDER BY MIN(entries.score) ASC, MIN(entries.time) ASC

エントリ テーブルからさらに情報が必要な場合は、これをサブクエリとして使用し、提示された情報 (facebook_id、スコア、時間) に再度結合して、ユーザーごとに 1 行を取得します。

2 回集計する必要があります。これが重要です。1 回目はユーザーの最小スコアを見つけ、もう一度そのユーザーとスコアの最小時間を見つけます。集計の順序を逆にすることもできますが、これが最も迅速にフィルター処理されるため、最も効率的であると予想されます。

また、最小スコアを使用するか、スコアを使用してグループ化するかの 2 回目の集計で、どちらが速いかを確認することもできます。

于 2012-06-29T14:51:39.053 に答える
2

ご協力いただきありがとうございます。@Penguatに最も近い答えがありました..これが、同じ問題を抱えている可能性のある人のための私の最後のクエリです...

SELECT f.facebook_id, f.name, f.score, f.time FROM
    (SELECT facebook_id, name, min(score)
    AS highscore FROM golf_entries
    WHERE time > 0
    GROUP BY facebook_id)
AS x
INNER JOIN golf_entries as f
ON f.facebook_id = x.facebook_id
AND f.score = x.highscore
ORDER BY score ASC, time ASC

再度、感謝します!

于 2012-06-29T15:33:39.340 に答える
1

ベストタイムが必要な場合は、MIN() 関数を使用することをお勧めします。スコアが低いほど、成績が良いとのことでした。

SELECT facebook_id, MIN(score), time, name, ... 
FROM entries 
GROUP BY facebook_id, time, name, ...
ORDER BY score, time
于 2012-06-29T14:13:48.527 に答える