MySQL: obtenga el registro más reciente

80

En la siguiente tabla, ¿cómo obtengo solo el registro más reciente de id=1según la columna de inicio de sesión y no los 3 registros?

+----+---------------------+---------+
| id | signin              | signout |
+----+---------------------+---------+
|  1 | 2011-12-12 09:27:24 | NULL    |
|  1 | 2011-12-13 09:27:31 | NULL    |
|  1 | 2011-12-14 09:27:34 | NULL    |
|  2 | 2011-12-14 09:28:21 | NULL    |
+----+---------------------+---------+
mejorar
fuente

Respuestas:

90

Utilice el agregado MAX(signin)agrupado por id. Esto enumerará los más recientes signinpara cada uno id.

SELECT 
 id, 
 MAX(signin) AS most_recent_signin
FROM tbl
GROUP BY id

Para obtener el registro único completo, realice una INNER JOINcontra una subconsulta que devuelve solo el MAX(signin)id.

SELECT 
  tbl.id,
  signin,
  signout
FROM tbl
  INNER JOIN (
    SELECT id, MAX(signin) AS maxsign FROM tbl GROUP BY id
  ) ms ON tbl.id = ms.id AND signin = maxsign
WHERE tbl.id=1
Michael Berkowski
fuente
Esto es lo que funcionó según su primera respuesta:SELECT id, MAX(signin) FROM tbl GROUP BY id WHERE id=1;
mejore el
Intenté implementar la segunda solución (para obtener toda la fila) en mi propia situación, pero siempre obtengo un conjunto de resultados vacío
rantsh
La respuesta de @rantsh xQbert tenía la versión correcta de lo que tenía originalmente arriba, pero prefiero la solución que acabo de cambiar.
Michael Berkowski
@MichaelBerkowski, ¿quisiste decir que prefieres mi solución? No me importaría recibir un voto positivo en mi respuesta si ese es el caso
rantsh
1
@rantsh Ah, no me había dado cuenta de que había agregado algo similar a lo que acabo de modificar, excepto vía en USINGlugar de explícito ON. Tienes un +1 :)
Michael Berkowski
83
SELECT *
FROM   tbl
WHERE  id = 1
ORDER  BY signin DESC
LIMIT  1;

El índice obvia sería en (id), o un índice de múltiples sobre (id, signin DESC).

Convenientemente para el caso, MySQL ordena los NULLvalores últimos en orden descendente. Eso es lo que normalmente desea si puede haber NULLvalores: la fila con el último no nulo signin.

Para obtener NULLvalores primero:

ORDER BY signin IS NOT NULL, signin DESC

Relacionado:

El estándar SQL no define explícitamente un orden de clasificación predeterminado para los NULLvalores. El comportamiento varía bastante entre diferentes RDBMS. Ver:

Pero no son los NULLS FIRST/ NULLS LASTlas cláusulas definidas en el estándar SQL y el apoyo de la mayoría de los RDBMS importantes, pero no por MySQL. Ver:

Erwin Brandstetter
fuente
5
¡Esta se siente como la forma más limpia de hacerlo!
karancan
Considere crear un índice para la columna de
inicio de sesión
Utilice SELECT TOP 1 *y elimine la LIMIT 1última línea. si usa SQL Server. Utilice lo anterior si MySQL o Postgres.
jaredbaszler
Más limpio. . . . . . . .
stigzler
¡Simple y limpio!
Jeremy Swagger
9

Sobre la base de la respuesta de @ xQbert, puede evitar la subconsulta Y hacerla lo suficientemente genérica como para filtrar por cualquier ID

SELECT id, signin, signout
FROM dTable
INNER JOIN(
  SELECT id, MAX(signin) AS signin
  FROM dTable
  GROUP BY id
) AS t1 USING(id, signin)
rantsh
fuente
Hola, ¿cómo funciona esta consulta y es más eficiente que la respuesta de xQbert? Ambas consultas se ejecutan aproximadamente al mismo tiempo para mí y no entiendo la parte de uso de la consulta que reemplaza lo que suele ser y sigue.
ZJS
3
Select [insert your fields here]
from tablename 
where signin = (select max(signin) from tablename where ID = 1)
xQbert
fuente
1
SELECT * FROM (SELECT * FROM tb1 ORDER BY signin DESC) GROUP BY id;
usuario3044573
fuente
1

Tuve un problema similar. Necesitaba obtener la última versión de la traducción del contenido de la página, en otras palabras, para obtener ese registro específico que tiene el número más alto en la columna de versión. Así que selecciono todos los registros ordenados por versión y luego tomo la primera fila del resultado (usando la cláusula LIMIT).

SELECT *
FROM `page_contents_translations`
ORDER BY version DESC
LIMIT 1
Ales
fuente
1

Manera simple de lograr

Sé que es una vieja pregunta.También puedes hacer algo como

SELECT * FROM Table WHERE id=1 ORDER BY signin DESC

En lo anterior, consulte el primer registro será el registro más reciente.

Para un solo registro, puede usar algo como

SELECT top(1) * FROM Table WHERE id=1 ORDER BY signin DESC

La consulta anterior solo devolverá un registro más reciente.

¡Salud!

Ajmal Jamil
fuente