1

次のようなsqlite3テーブルがあります。

sqlite> select * from scores;
team        Name        score
----------  ---------   ----------
A           Name1       93
A           Name2       96
A           Name3       78
A           Name4       82
B           Name5       83
B           Name6       30
B           Name7       99
B           Name8       71
B           Name8A      45
B           Name8C      70
c           Name9       87
c           Name10      87
c           Name11      81
c           Name12      71
c           Name13      91

チーム数は多く(約30チーム)、各チームには多くのメンバーがいます(実質10,000レコード以上)。次のように、各チームの最初の N 人の勝者を取得したいだけです (簡略化のため、この例では N=3 です)。

A     Name2   96
A     Name1   93
A     Name4   82
B     Name7   99
B     Name5   83
B     Name8   71
C     Name13  91
C     Name9   87
C     Name10  87

同じチームでのスコアによってランク付けされます。

sqlite3クエリを使用してこの結果を取得するには? 誰でも手がかりを与えることができますか?どうもありがとう。

ところで、「名前」フィールドは一意ではなく、(チーム、名前) のみが一意です。つまり、同じ名前が異なるチームに表示される可能性があります。

4

3 に答える 3

0

テーブルから各チームの上位 N の結果を選択する代わりに、各チームscoresの上位 N の結果を含むテーブルから結果セットを選択できます。

leaderboardに等しい構造を持つ、必要なデータを持つテーブルを と呼びましょうscores

に挿入されたデータを に複製しscoreますleaderboard。次に、各チームの最高の N スコアのみを保持し、leaderboard十分に高くないスコアを削除します。そのためには、次のようなトリガーが必要です。

CREATE TRIGGER "update_top_scores"
AFTER INSERT ON scores  
BEGIN
    -- Add the record to leaderboard
    INSERT INTO leaderboard (team, name, score) VALUES (NEW.team, NEW.name, NEW.score);
    -- only keep the top 30 records of each teams 
    DELETE FROM leaderboard WHERE team = NEW.team AND name NOT IN (SELECT name FROM leaderboard WHERE team = NEW.team ORDER BY score DESC LIMIT 30);

END

これで、1 つの単純なクエリを使用して、各チームから上位 N 点のスコアを取得できます。

SELECT * FROM leaderboard;

db ファイルに新しいテーブルやトリガーを入れたくない場合は、次のことを行うことをお勧めします。

  1. 新しいテーブルleaderboardを作成し、dummy_scores
  2. のトリガーを作成しますdummy_scores
  3. INSERT INTO ... SELECTステートメントを使用して からscoreにデータをコピーしますdummy_score。これにより、トリガーもアクティブになります
  4. から結果を得るSELECT * FROM leaderboard
  5. drop leaderboarddummy_scoresおよび db ファイルからのトリガー

これで、元の db ファイルと必要な結果が得られました。

于 2016-07-28T08:31:16.013 に答える
0

あなたはこれを試すことができます

set @currcount=0,@currvalue='', @N=4;
SELECT team, Name, score FROM ( SELECT team, Name, score, @currcount :=    
IF(@currvalue = team, @currcount + 1, 1) as rank, @currvalue := team FROM 
scores ORDER BY team DESC) as what WHERE rank<@N order by team asc, score desc
于 2016-07-26T10:32:11.617 に答える