sql >> Databáze >  >> RDS >> Mysql

MySQL vybere nejlepších X záznamů pro každého jednotlivce v tabulce

Tento druh dotazu lze přeformulovat ve smyslu „greatest-n-per-group“, kde chcete, aby prvních 10 skóre na „skupinu“ byly hodnoty „foo“.

Navrhuji, abyste se podívali na tento odkaz který se s touto otázkou vypořádává úžasně, začíná způsobem, který dává smysl provést váš dotaz, a postupně jej optimalizuje.

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;

Pokud jste to chtěli provést napříč všemi úrovně foo (tj. představte si, že děláte GROUP BY foo ), můžete vynechat where foo in ... řádek.

V podstatě vnitřní dotaz (SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC ) popadne foo a score z tabulky, nejprve seřaďte podle foo a poté skóre sestupně.

@num := ... jen se zvyšuje každý řádek a resetuje se na 1 pro každou novou hodnotu foo . To znamená @num je pouze číslo řádku/hodnocení (zkuste spustit vnitřní dotaz samostatně, abyste viděli, co tím myslím).

Vnější dotaz pak vybere řádky, kde je číslo pořadí/řádku menší nebo rovno 10.

POZNÁMKA:

Váš původní dotaz s UNION odstraní duplikáty, takže pokud 10 nejlepších skóre pro foo='abc' je všech 100, bude vrácen pouze jeden řádek (protože (foo,score) pár se replikuje 10krát). Tento vrátí duplikáty.




  1. Chcete rozdělit řetězec v mysql pomocí SUBSTRING_INDEX

  2. Získejte informace o zobrazení pomocí zobrazení informačního schématu VIEWS na serveru SQL Server

  3. SQL:Seřaďte podle priority, ale nulu uveďte jako poslední

  4. Vypočítejte pracovní dobu mezi dvěma daty