sql >> Databasteknik >  >> RDS >> Mysql

MySQL väljer topp X-poster för varje individ i tabellen

Den här typen av sökning kan omformuleras i "största-n-per-grupp", där du vill att de 10 bästa poängen per "grupp" ska vara värdena för "foo".

Jag föreslår att du tar en titt på denna länk som hanterar denna fråga fantastiskt, börjar med ett sätt som är vettigt att utföra din fråga och gradvis optimera 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;

Om du ville utföra detta i alla nivåer av foo (dvs. tänk dig att göra en GROUP BY foo ), kan du utelämna where foo in ... rad.

I grund och botten den inre frågan (SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC ) tar tag i foo och score från bordet, beställ först efter foo och sedan poäng fallande.

@num := ... ökar bara varje rad och återställer till 1 för varje nytt värde på foo . Det vill säga @num är bara ett radnummer/rang (försök att köra den inre frågan på egen hand för att se vad jag menar).

Den yttre frågan väljer sedan rader där rang-/radnumret är mindre än eller lika med 10.

OBS:

Din ursprungliga fråga med UNION tar bort dubbletter, så om de 10 bästa poängen för foo='abc' är alla 100 kommer bara en rad att returneras (eftersom (foo,score) paret replikeras 10 gånger). Den här kommer att returnera dubbletter.




  1. Datatrunkering:Felaktigt datetime-värde:''

  2. Simulering av CONNECT BY PRIOR av Oracle i SQL Server

  3. Prestandamyter:Tabellvariabler finns alltid i minnet

  4. Exportera lagrat procedurresultat till Excel i SSMS