sql >> Database teknologi >  >> RDS >> Mysql

MySQL vælger top X-poster for hver enkelt person i tabellen

Denne form for forespørgsel kan omformuleres i en "største-n-pr-gruppe" forstand, hvor du ønsker, at de 10 bedste resultater pr. "gruppe" skal være værdierne for "foo".

Jeg foreslår, at du tager et kig på dette link der behandler dette spørgsmål fantastisk, og starter med en måde, der giver mening at udføre din forespørgsel på og gradvist optimere den.

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;

Hvis du ville udføre dette på tværs af alle niveauer af foo (dvs. forestil dig at lave en GROUP BY foo ), kan du udelade where foo in ... linje.

Dybest set den indre forespørgsel (SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC ) griber foo og score fra bordet ved at bestille først efter foo og derefter score faldende.

@num := ... øger bare hver række og nulstiller til 1 for hver ny værdi af foo . Det vil sige @num er kun et rækkenummer/rangering (prøv at køre den indre forespørgsel alene for at se, hvad jeg mener).

Den ydre forespørgsel vælger derefter rækker, hvor rang-/rækkenummeret er mindre end eller lig med 10.

BEMÆRK:

Din oprindelige forespørgsel med UNION fjerner dubletter, så hvis top 10 scorer for foo='abc' er alle 100, vil kun én række blive returneret (da (foo,score) par er replikeret 10 gange). Denne vil returnere dubletter.




  1. Hvordan fungerer SQL's konverterfunktion, når datetime konverteres til float?

  2. Sådan formindskes/renses ibdata1-fil i MySQL

  3. Hvordan kan jeg tilføje kommentarer i MySQL?

  4. ClusterControl - Advanced Backup Management - PostgreSQL