Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Dołącz do pojedynczego wiersza z tabeli w MySQL

Jest to największy problem na grupę, który często pojawia się na Stack Overflow.

Oto moja zwykła odpowiedź:

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

;

Innymi słowy, mając dane s, spróbuj znaleźć wynik s2 dla tego samego zawodnika, ale z wcześniejszą datą. Jeśli nie zostanie znaleziony wcześniejszy wynik, s jest najwcześniejszym.

Odpowiedz na swój komentarz na temat krawatów:Musisz mieć politykę, której użyć w przypadku remisu. Jedną z możliwości jest to, że jeśli używasz automatycznego przyrostu kluczy podstawowych, ten z najmniejszą wartością jest wcześniejszy. Zobacz dodatkowy termin w sprzężeniu zewnętrznym poniżej:

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

;

Zasadniczo musisz dodać terminy rozstrzygania remisów, dopóki nie dojdziesz do kolumny, która na pewno będzie unikalna, przynajmniej dla danego gracza. Klucz główny tabeli jest często najlepszym rozwiązaniem, ale widziałem przypadki, w których odpowiednia była inna kolumna.

Jeśli chodzi o komentarze, które podzieliłem się z @OMG Ponies, pamiętaj, że tego typu zapytania bardzo korzystają z właściwego indeksu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Uzyskiwanie połączenia PHP PDO z mysql_connect()?

  2. Rozwiązanie podzapytania zwraca więcej niż 1 błąd wiersza

  3. Problem z lokalnym hostem MySQL / 127.0.0.1

  4. Błąd interfejsu (0, '')

  5. Nielegalna mieszanka zestawień (latin1_swedish_ci,COERCIBLE) i (utf8_general_ci,IMPLICIT) dla operacji „find_in_set”