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

Verbinden Sie einzelne Zeilen aus einer Tabelle in MySQL

Dies ist das Größte-n-pro-Gruppen-Problem, das häufig bei Stack Overflow auftritt.

Hier ist meine übliche Antwort:

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

;

Mit anderen Worten, versuchen Sie bei gegebener Punktzahl s eine Punktzahl s2 für denselben Spieler zu finden, aber mit einem früheren Datum. Wenn kein früherer Score gefunden wird, ist s der früheste.

Zu Ihrem Kommentar zu Unentschieden:Sie müssen eine Richtlinie haben, für die Sie im Falle eines Unentschiedens eine verwenden können. Eine Möglichkeit ist, wenn Sie automatisch inkrementierende Primärschlüssel verwenden, ist derjenige mit dem geringsten Wert der frühere. Siehe den zusätzlichen Begriff im äußeren Join unten:

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

;

Grundsätzlich müssen Sie Tiebreaker-Begriffe hinzufügen, bis Sie zu einer Spalte gelangen, die garantiert eindeutig ist, zumindest für den jeweiligen Spieler. Der Primärschlüssel der Tabelle ist oft die beste Lösung, aber ich habe Fälle gesehen, in denen eine andere Spalte geeignet war.

Denken Sie in Bezug auf die Kommentare, die ich mit @OMG Ponies geteilt habe, daran, dass diese Art von Abfrage enorm vom richtigen Index profitiert.