Mysql
 sql >> Base de données >  >> RDS >> Mysql

Joindre une seule ligne à partir d'une table dans MySQL

Il s'agit du plus grand problème de n-par-groupe qui survient fréquemment sur Stack Overflow.

Voici ma réponse habituelle :

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

;

En d'autres termes, étant donné le score s, essayez de trouver un score s2 pour le même joueur, mais avec une date antérieure. Si aucun score antérieur n'est trouvé, alors s est le plus ancien.

Concernant votre commentaire sur les égalités :vous devez avoir une politique pour laquelle utiliser en cas d'égalité. Une possibilité est que si vous utilisez des clés primaires à incrémentation automatique, celle qui a le moins de valeur est la plus ancienne. Voir le terme supplémentaire dans la jointure externe ci-dessous :

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

;

Fondamentalement, vous devez ajouter des termes de départage jusqu'à ce que vous arriviez à une colonne qui est garantie d'être unique, au moins pour le joueur donné. La clé primaire de la table est souvent la meilleure solution, mais j'ai vu des cas où une autre colonne convenait.

Concernant les commentaires que j'ai partagés avec @OMG Ponies, rappelez-vous que ce type de requête bénéficie énormément du bon index.