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

MySQL LEFT JOIN utilisant MAX &GROUP BY sur la table jointe ?

Le problème "le plus récent par groupe" est extrêmement commun en SQL. Il existe d'innombrables exemples de solutions à ce problème sur ce seul site.

Si vos horodatages sont uniques par activité de membre :

SELECT
  m.id,
  m.name,
  a.code activity_code,
  a.timestamp activity_timestamp,
  a.description activity_description
FROM
  members m
  INNER JOIN activities a ON a.member_id = m.id
WHERE
  a.timestamp = (SELECT MAX(timestamp) FROM activities WHERE member_id = m.id)

alternativement, si votre ID d'activité augmente de manière monotone avec le temps :

  ...
WHERE
  a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)

Vous n'avez pas besoin de grouper. Mais la requête bénéficiera d'un index sur les activities sur (member_id, timestamp) ou (member_id, id) , respectivement.

MODIFIER

Pour afficher tous les membres qui n'ont pas enregistré d'activité, utilisez une jointure gauche comme celle-ci.

SELECT
  m.id,
  m.name,
  a.code activity_code,
  a.timestamp activity_timestamp,
  a.description activity_description
FROM
  members m
  LEFT JOIN activities a ON 
    a.member_id = m.id
    AND a.timestamp = (SELECT MAX(timestamp) FROM activities WHERE member_id = m.id)

Notez qu'il n'y a pas de WHERE clause. Sémantiquement, WHERE est appliqué après les jointures sont faites. Ainsi, une clause WHERE supprimerait les lignes ajoutées par LEFT JOIN, donnant effectivement le même résultat que l'INNER JOIN d'origine.

Mais si vous appliquez le prédicat supplémentaire directement dans la condition de jointure, le LEFT JOIN fonctionnera comme prévu.