2016-07-26 6 views
1

ich eine sqlite3 Tabelle wie folgt aus:Wie wählt man die ersten N Gewinner jedes Teams aus SQLITE aus?

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 

Es gibt viele Teams (ca. 30 Teams), jedes Team hat viele Mitglieder (mehr als 10.000 Datensätze in real). Ich habe möchte nur die ersten N Gewinner der einzelnen Teams wie folgt aus (zur Vereinfachung, N = 3 in diesem Beispiel):

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 

und sie zeichnen sich durch ihre Punktzahl withing der gleichen Mannschaft rangiert.

Wie bekomme ich dieses Ergebnis mit sqlite3 Abfrage? kann jemand einen Hinweis geben? vielen Dank.

btw, das Feld 'Namen' ist nicht eindeutig, nur (Team, Name) ist einzigartig, das heißt derselbe Name in verschiedenen Teams auftreten kann.

+0

Wählen Sie * aus Punkten mit Werten> 99; und Ihre Gesamtzahl erhalten Sie dann zählen (*), wo Scores> 99; –

Antwort

0

können Sie versuchen, dieses

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 
+0

Dies funktioniert nicht in SQLite. –

+0

Wie CL sagte, das ist SQLite3, Ihr Code wird nicht funktionieren. – user2545464

0

Question: how to select first N row of each group? Laut Gordon Linoff Methode, ich diesen Code herausgefunden:

select * from dayobs a 
    where a.rowid in 
    (select b.rowid from dayobs b where b.station==a.station order by b.rain desc limit 5); 

Es funktioniert, aber sehr, sehr langsam, SQLite gibt jeden Datensatz mehr als 1 Minute! Diese Abfrage dauert etwa eine halbe Stunde. Offensichtlich kann dies in einem echten Job nicht passieren. Ich denke, es muss einen Weg geben, es effizienter zu machen.

0

Anstatt das oberste N-Ergebnis jedes Teams aus der Tabelle scores auszuwählen, können wir das Ergebnis aus einer Tabelle auswählen, die das oberste N-Ergebnis jedes Teams enthält.

Nennen wir die Tabelle mit den Daten, die wir benötigen, als leaderboard, die die Struktur scores hat.

Wir duplizieren die Daten, die in score eingefügt wurden, zu leaderboard. Dann behalten wir nur die besten N-Werte jedes Teams in leaderboard und löschen alle Punkte, die nicht hoch genug sind.Um dies zu tun, müssen wir einen Trigger wie folgt:

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 

So, jetzt können wir das Top-N-Scores von jedem Team mit einer einfachen Abfrage erhalten

SELECT * FROM leaderboard; 

Angenommen, Sie don ‚t eine neue Tabelle oder Trigger in Ihrer db-Datei haben wollen, empfehle ich Ihnen das Folgende tun

  1. neue Tabelle erstellen leaderboard und dummy_scores
  2. erstellen Sie den Auslöser für dummy_scores
  3. Verwendung INSERT INTO ... SELECT Auszugsdaten score-dummy_score, zu kopieren, die zu den Trigger aktiviert
  4. das Ergebnis aus SELECT * FROM leaderboard
  5. Tropfen leaderboard, dummy_scores und den Abzug von db-Datei erhalten

Jetzt haben Sie die ursprüngliche db-Datei und das Ergebnis, das Sie benötigen.