Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL wählt die Top-X-Einträge für jede Person in der Tabelle aus

Diese Art von Abfrage kann im Sinne von „größte n pro Gruppe“ umformuliert werden, wobei Sie möchten, dass die Top-10-Ergebnisse pro „Gruppe“ Werte von „foo“ sind.

Ich schlage vor, Sie werfen einen Blick auf dieser Link die sich wunderbar mit dieser Frage auseinandersetzt, indem sie mit einer sinnvollen Art und Weise beginnt, Ihre Abfrage durchzuführen, und sie schrittweise optimiert.

set @num := 0, @foo := '';
select foo, score
from (
   select foo, score,
      @num := if(@foo = foo, @num + 1, 1) as row_number,
      @foo := foo as dummy
  from tablebar
  where foo IN ('abc','def')
  order by foo, score DESC     
) as x where x.row_number <= 10;

Wenn Sie dies für alle durchführen möchten Ebenen von foo (d.h. stellen Sie sich vor, Sie machen ein GROUP BY foo ), können Sie where foo in ... weglassen Linie.

Grundsätzlich die innere Abfrage (SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC ) greift foo und score aus der Tabelle, zuerst nach foo bestellen und dann Punktzahl absteigend.

Der @num := ... erhöht einfach jede Zeile und wird für jeden neuen Wert von foo auf 1 zurückgesetzt . Das heißt, @num ist nur eine Zeilennummer/Rang (versuchen Sie, die innere Abfrage selbst auszuführen, um zu sehen, was ich meine).

Die äußere Abfrage wählt dann Zeilen aus, bei denen die Rang-/Zeilennummer kleiner oder gleich 10 ist.

HINWEIS:

Ihre ursprüngliche Anfrage mit UNION entfernt Duplikate, also wenn die Top 10 für foo='abc' punkten alle 100 sind, wird nur eine Zeile zurückgegeben (da der (foo,score) Paar wird 10 Mal repliziert). Dieser gibt Duplikate zurück.