sql >> Base de Datos >  >> RDS >> Mysql

MySQL LEFT JOIN usando MAX &GROUP BY en la tabla unida?

El problema de "más reciente por grupo" es extremadamente común en SQL. Hay innumerables ejemplos de soluciones a este mismo problema solo en este sitio.

Si sus marcas de tiempo son únicas por actividad de miembro:

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)

alternativamente, si su ID de actividad aumenta monótonamente con el tiempo:

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

No es necesario agrupar. Pero la consulta se beneficiará de un índice sobre activities sobre (member_id, timestamp) o (member_id, id) , respectivamente.

EDITAR

Para mostrar a los miembros que no han registrado una actividad, use una combinación izquierda como esta.

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)

Tenga en cuenta que no hay WHERE cláusula. Semánticamente, DONDE se aplica después las uniones están hechas. Entonces, una cláusula WHERE eliminaría las filas que agregó LEFT JOIN, dando efectivamente el mismo resultado que INNER JOIN original.

Pero si aplica el predicado adicional directamente en la condición de unión, LEFT JOIN funcionará como se esperaba.