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

Připojte jeden řádek z tabulky v MySQL

Toto je největší problém-n-per-group, který se na Stack Overflow často vyskytuje.

Zde je moje obvyklá odpověď:

select
  p.name        player,
  s.date        first_score,
  s.points      points

from  players p

join  scores  s
  on  s.player_id = p.id

left outer join scores  s2
  on  s2.player_id = p.id
      and s2.date < s.date

where
  s2.player_id is null

;

Jinými slovy, při daném skóre s se pokuste najít skóre s2 pro stejného hráče, ale s dřívějším datem. Pokud není nalezeno žádné dřívější skóre, pak s je nejstarší.

K vašemu komentáři ohledně remíz:Musíte mít zásady, které se mají použít v případě remízy. Jednou z možností je, že pokud použijete automaticky se zvyšující primární klíče, ten s nejmenší hodnotou je ten dřívější. Viz další termín ve vnějším spojení níže:

select
  p.name        player,
  s.date        first_score,
  s.points      points

from  players p

join  scores  s
  on  s.player_id = p.id

left outer join scores  s2
  on  s2.player_id = p.id
      and (s2.date < s.date or s2.date = s.date and s2.id < s.id)

where
  s2.player_id is null

;

V zásadě musíte přidávat výrazy pro nerozhodný výsledek, dokud se nedostanete na sloupec, který je zaručeně jedinečný, alespoň pro daného hráče. Primární klíč tabulky je často nejlepším řešením, ale viděl jsem případy, kdy byl vhodný jiný sloupec.

Pokud jde o komentáře, které jsem sdílel s @OMG Ponies, nezapomeňte, že tento typ dotazu velmi těží ze správného indexu.



  1. Fulltextové vyhledávání v Postgres nebo CouchDB?

  2. Časový limit připojení pro DriverManager getConnection

  3. SELECT INTO a chyba nedeklarované proměnné

  4. Jak AKTUALIZOVAT tabulku pomocí SUM() a COUNT() ve stejné tabulce do různých sloupců