miércoles, 22 de agosto de 2012

GROUP BY de los últimos registros en MySQL

Esta semana me encontré con un problema. Tenia una tabla similar a la siguiente:

id nro_colectivo fecha chofer
1 800 2012-08-19 Pablo
2 801 2012-08-19 Juan
3 802 2012-08-20 Mariano
4 802 2012-08-21 Pablo
5 800 2012-08-21 Daniel

Y necesitaba obtener el ultimo registro de cada colectivo. Osea:

id nro_colectivo fecha chofer
2 801 2012-08-19 Juan
4 802 2012-08-21 Pablo
5 800 2012-08-21 Daniel

Si hacemos la siguiente consulta:
  SELECT * FROM tabla GROUP BY nro_colectivo
este sería el resultado:

id nro_colectivo fecha chofer
1 800 2012-08-19 Pablo
2 801 2012-08-19 Juan
3 802 2012-08-20 Mariano

Como se puede ver lo que devolvió fue el primer registro de cada uno. Si agregáramos un ORDER BY id DESC obtendríamos las mismas filas solo que ordenadas de mayor a menor, Osea 3, 2, 1.

Para obtener el resultado deseado hay que hacer la consulta de la siguiente manera:
  SELECT * FROM ( SELECT * FROM tabla ORDER BY id DESC )sub GROUP BY nro_colectivo

Lo que estoy haciendo es una consulta anidada. Osea hago una consulta que me traiga toda la tabla, pero ordenada en forma descendente, le doy un nombre, 'sub' en este caso, y a esta le hago una segunda consulta pidiendo que me agrupe los datos por el numero de colectivo.

Espero que les sirva.

17 comentarios:

  1. gracias amigo, era lo que buscaba y me sirvio de mucho.

    ResponderBorrar
  2. Muchas gracias, justo lo que necesitaba, me salvaste de un apuro :)

    ResponderBorrar
  3. Me soluciono el problema. Gracias

    ResponderBorrar
  4. graciassssssssssssssssss ya solucione mi problemaaa

    ResponderBorrar
  5. graciasssss ha solucionado mi problemaaa :)

    ResponderBorrar
  6. Muy groso!!! excelente. Muchas gracias

    ResponderBorrar
  7. Muchisimas gracias, era lo que justo necesitaba para cargar un buzon de mensajes y seleccione los ultimos mensajes sin repetirse. Me salvaste el dia

    ResponderBorrar
  8. PURA VIDA por compartir su conocimiento!

    EL PODER, ES SABER... Y EL SABER PERTENECE A LA HUMANIDAD. kqc, 2014.

    ResponderBorrar
  9. Respuestas
    1. Puedes hacer una unión

      SELECT * FROM (
      (SELECT * FROM tabla ORDER BY id DESC )
      UNION
      (SELECT * FROM tabla ORDER BY id DESC )
      )sub GROUP BY nro_colectivo

      Recuerda que para hacer la unión los dos select deben devolver el mismo numero de columnas y del mismo tipo, por lo cual no hace falta que las dos tablas sean exactamente iguales, pero si debes armar la consulta de forma que lo que devuelvan los select sea similar.

      Borrar
  10. eso es excelente para 3 registro, pero lo hago con un tabla de 80 millones de registros, y se muere

    ResponderBorrar
    Respuestas
    1. En una tabla con 80 millones de registros no te va a funcionar rápido ningún tipo de group by, te recomiendo crear otra tabla para guardar unicamente los últimos registros, de forma que cada vez que ingreses un registro en la tabla principal reemplaces el registro del colectivo ingresado en la tabla con los últimos registros. De esa forma solo tendrías que hacer un SELECT * FROM tabla_ult_reg

      Borrar
  11. Hola amigos, Y como podría meterle un inner join de ese tipo de consulta:
    --------------------
    SELECT * FROM ( SELECT C.Id,C.IdAmistad,C.Mensaje,C.IdEmisor,C.IdReceptor,C.Tipo,C.FechaMensaje FROM FX_Chat C
    WHERE C.IdReceptor = 5 and C.IdEmisor IN (1,4,6,7) or C.IdEmisor = 5 and C.IdReceptor IN (1,4,6,7) ORDER BY Id DESC)
    sub GROUP BY IdAmistad


    --------------------
    Id IdAmistad Mensaje IdEmisor IdReceptor Tipo Fecha
    703 3 Hola amigoooo 5 6 1 2019-01-15 11:08:37
    --------------------
    Quisiera mostrar el nombre de la persona, y su foto de perfil.
    si se como hacer el inner join lo que no se es como implementar en esa consulta.

    ResponderBorrar

Sobre el autor