query functions example any_value and mysql

functions - MySQL IZQUIERDA ÚNETE usando MAX & GROUP BY en la tabla unida?



mysql group by condition (3)

Tengo dos tablas (miembros y actividades) y estoy tratando de consultar a los miembros con la actividad más reciente para cada miembro. Lo tengo trabajando con dos consultas (una para obtener los miembros y una segunda con un máximo (id) y grupo por (miembro) en las actividades) y algo de código para combinar los datos. Estoy seguro de que se puede hacer con una sola consulta, pero no puedo resolverlo. ¿Algunas ideas?

mesa de miembros

id, name 1, Shawn 2, bob 3, tom

mesa de actividades

id, member_id, code, timestamp, description 1, 1, 123, 15000, baked a cake 2, 1, 456, 20000, ate dinner 3, 2, 789, 21000, drove home 4, 1, 012, 22000, ate dessert

resultado deseado:

id, name, activity_code, activity_timestamp, activity_description 1, shawn, 012, 22000, ate dessert 2, bob, 789, 21000, drove home 3, tom, null, null, null


El problema "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 sellos de tiempo son únicos 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 necesitas agrupar. Pero la consulta se beneficiará de un índice de activities sobre (member_id, timestamp) o (member_id, id) , respectivamente.

EDITAR

Para mostrar a los miembros que no hayan 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 ninguna cláusula WHERE . Semánticamente, WHERE se aplica después de que se realizan las uniones. Por lo tanto, una cláusula WHERE eliminaría las filas que agregó la IZQUIERDA IZQUIERDA, dando efectivamente el mismo resultado que la JUNTA INTERNA original.

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


SELECT members.id , members.name, activities.code AS activity_code, activities.timestamp AS activity_timestamp, activities.description AS activity_description FROM members LEFT JOIN activities ON members.id = activities.member_id LEFT JOIN ( SELECT activities.member_id MAX(activities.id) AS id FROM activities GROUP BY activities.member_id ) AS t1 ON activities.id = t1.id WHERE t1.id IS NOT NULL


Select max(a.id), m.name, a.activity_code, a.activity_timestamp, a.activity_description From members m Left join activities a on a.member_id=m.id Group by m.name, a.activity_code, a.activity_timestamp, a.activity_description